读书人

Java 设计方式-装饰器模式和代理模式

发布时间: 2012-12-26 14:39:28 作者: rapoo

Java 设计模式-装饰器模式和代理模式

1.装饰器模式

1.1 定义

动态地给对象添加新的功能,相比子类继承方式有更大的灵活性。比如Java中的InputStream,使用了BufferedInputStream进行了包装实现了buffer data的功能。

?

使用装饰器模式,符合Open-Closed 原则,对修改封闭,对扩展(增加)开放。

?

1.2 使用场景

装饰器模式适用于完成类似的功能

?


2.代理模式

2.1 定义

有时候,我们需要对实际对象的访问进行控制,我们对这个层的访问进行重新封装成一个新的对象,让客户端直接访问这个新的对象。

?

2.2 使用场景

1.代理一些开销比较大的对象,可以实现延时加载

2.安全控制,缓存对象,异常处理,记录日志等等

3.分布式对象访问控制,使得客户端对象可以像访问本地服务一样访问远程服务

?

2.3 静态代理

静态代理类似于装饰器模式

?

package proxy;
/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public interface UserManager {
??? public void addUser(String userName);
}

?

package proxy;
/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public class UserManagerImple implements UserManager {
??? public void addUser(String userName){
??? ??? ?System.out.println(" do add user ... "+userName);
??? }
}

?

package proxy;
/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public class StaticProxy implements UserManager {
??? private UserManager userManager;
???
??? public StaticProxy(UserManager userManager){
??? ??? this.userManager = userManager;
??? }
???
??? public void addUser(String userName){
??? ??? System.out.println("Static proxy here");
??? ??? userManager.addUser(userName);
??? }

}

?

package proxy;
/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public class StaticProxyTest {
???
??? public static void main(String[] args) {
??? ??? UserManager userManager = new UserManagerImple();
??? ??? UserManager userManagerProxy = new StaticProxy(userManager);
??? ??? userManagerProxy.addUser("Tommy");
??? }

}

?

2.4 动态代理

动态代理只能代理接口,而且可以代理不同的接口,例如如果要在所有的类方法执行过程中,执行权限控制,只要在代理的代理方法中,传入不同的接口就可以实现,动态代理可以代理所有的方法。而静态代理只能在每个方法中加入权限控制代码,因此,动态代理的扩展性和代码的侵入性更小。

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public class DynamicProxy? implements InvocationHandler{
??? private Object object;

??? @Override
??? public Object invoke(Object proxy, Method method, Object[] args)
??? ??? ??? throws Throwable {
??? ??? System.out.println("Put other functions here");
??? ??? return method.invoke(object, args);
??? }
??? public Object newProxy(Object object){
??? ??? this.object = object;
??? ??? return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
??? }
}
package proxy;
/**
?*
?*<p>Test</p>
?*<p>Description:</P>
?*<p>Company:Cisco CAS</p>
?*<p>Department:CAS</p>
?*@Author: Tommy Zhou
?*@Since: 1.0
?*@Version:Date:2011-5-5
?*
?**/

public class DynamicProxyTest {
???
??? public static void main(String[] args) {
??? ??? DynamicProxy proxy = new? DynamicProxy();
??? ??? UserManager userManager= new UserManagerImple();
??? ??? UserManager userManager1 = (UserManager)proxy.newProxy(userManager);
??? ??? userManager1.addUser("Tommy");???
??? }
}

?

3.两种设计模式之间的区别和联系

读书人网 >软件开发

热点推荐