Java设计模式----代理模式

来源:互联网 发布:淘宝客服礼貌用语 编辑:程序博客网 时间:2024/05/19 00:42

顾名思义,代理模式就是将对象以代理的方式对外提供访问。在某些情况下,客户端不能或者不想访问某个对象的时候,代理就可以在客户端与对象之间起到中介的作用。

也就是说,在两个类需要通信时,引入代理可以讲两个类之间的关系解耦,客户端只需了解代理类即可。

根据代理的创建时段,可以分为静态代理和动态代理。

静态代理

静态代理类由程序员创建源代码或者特定工具自动生成源代码,在编译时期就已经存在,在程序运行前.class文件已经存在。
下面是实例代码:
Service.java
public interface Service {public void add(int id, String name);public void delete(int id);public String find(int id);public void modify(String id, String name);}
ServiceImpl.java
public class ServiceImpl implements Service {@Overridepublic void add(int id, String name) {System.out.println("add id="+id+",name="+name);}@Overridepublic void delete(int id) {System.out.println("delete id="+id);}@Overridepublic String find(int id) {System.out.println("find id="+id);return "id="+id+",name=?";}@Overridepublic void modify(String id, String name) {System.out.println("modify id="+id+",name="+name);}}
ServiceProxy.java
public class ServiceProxy implements Service {private Service service;//委托代理类//通过构造方法传入委托代理类public ServiceProxy(Service service) {this.service = service;}@Overridepublic void add(int id, String name) {System.out.println("begin of add()");//添加日志service.add(id, name);System.out.println("end of add()");//添加日志}@Overridepublic void delete(int id) {System.out.println("begin of delete()");//添加日志service.delete(id);System.out.println("begin of delete()");//添加日志}@Overridepublic String find(int id) {System.out.println("begin of find()");//添加日志service.find(id);System.out.println("begin of find()");//添加日志return "id="+id+",name=?";}@Overridepublic void modify(String id, String name) {System.out.println("begin of modify()");//添加日志service.modify(id, name);System.out.println("begin of modify()");//添加日志}}
ProxyTest.java
public class ProxyTest {public static void main(String[] args) {Service service = new ServiceImpl();ServiceProxy serviceProxy = new ServiceProxy(service);serviceProxy.add(1, "小二");}}
运行结果:
begin of add()add id=1,name=小二end of add()

1)代理类(ServiceProxy)与委托类(ServiceImpl)实现了同一个接口(Service),即代理类与委托类实现了相同的方法,这样就导致了代码的重复出现;
2)如果接口中增加方法或者减少方法,代理类与委托类都要实现或者删除方法,代码维护部方便;
3)可以看到ServiceProxy中只能够接收Service类型,也就是说该代理只能代理一种类型的对象,多种类型就要写多种代理;
4)代理可以对委托类进行统一管理,如上面代码所示,我们需要在ServiceImpl中每个方法加上添加日志功能,一般不希望修改ServiceImpl类,所以添加一个代理类就可以实现,这样符合开闭原则。

动态代理

动态代理是在程序运行期间通过反射机制动态创建的。
从上面的静态代理中可以发现一个代理类只能服务一个接口,这样在开发中会产生很多的代理类,而动态代理可以为多个接口服务。
来看看动态代理的实例代码,其中Service.java与ServiceImpl.java的代码与静态代理是一样的,这里就不贴出来了。
MyInvocationHandler.java
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyInvocationHandler implements InvocationHandler {private Object target;//接收对象为Object类型,可以接收各种类型的接口public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("begin of invoke()");//添加日志Object result = method.invoke(target, args);System.out.println("end of invoke()");//添加日志return result;}public Object getProxy() {ClassLoader loader = Thread.currentThread().getContextClassLoader();Class<?>[] interfaces = target.getClass().getInterfaces();return Proxy.newProxyInstance(loader, interfaces, this);}}
ProxyTest.java
import java.lang.reflect.Proxy;public class ProxyTest {public static void main(String[] args) {Service service = new ServiceImpl();MyInvocationHandler handler = new MyInvocationHandler(service);Service serviceProxy = (Service) handler.getProxy();serviceProxy.add(1,"小二");serviceProxy.delete(2);//Service serviceProxy1 = (Service) Proxy.newProxyInstance(//service.getClass().getClassLoader(), service.getClass().getInterfaces(), handler);//serviceProxy1.add(1,"小二");}}
运行结果:
begin of invoke()add id=1,name=小二end of invoke()begin of invoke()delete id=2end of invoke()
动态代理相比较于静态代理,最大的有点就是接口中声明的所有方法都集中放在一个方法(InvocationHandler.invoke())中处理,这样接口数量多的时候,我们不需要写多个代理类。




1 0
原创粉丝点击