代理模式

代理模式

定义:为一个对象提供一个替身或占位符以控制对这个对象的访问。被代理的对象可以是远程的对象、创建开销大的对象、需要安全控制的对象。

角色
  1. subject:真正对象与代理对象都要实现的接口,允许客户可以像处理真正对象一样处理代理对象
  2. proxy:代理对象,并持有真正对象的引用,必要时可以将请求转发给真正对象。
  3. realSubject:真正对象,代理对象控制对其访问
类型
  1. 远程代理:管理客户端与远程之间的交互
  2. 虚拟代理:创建开销大的对象的代表。虚拟代理经常知道我们真正需要一个对象的时候才创建它,当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。
  3. 动态代理:
  4. 保护代理:基于调用者控制对对象方法的访问
  5. 防火墙代理(Firewall Proxy):控制网络资源访问,保护主题免于“坏客户”的侵害
  6. 智能引用代理(Smart Reference Proxy):主题被访问时,进行额外的动作
  7. 缓存代理(Caching Proxy):为开销大的运算结果提供暂时的存储,也允许多个客户共享结果,以减少计算或网络延迟。(web服务器代理,内容管理,出版系统)
  8. 同步代理(Synchronization Proxy)多线程的情况下为主题提供安全的访问。(javaSpaces为分散式环境内的潜在对象集合提供同步访问控制)
  9. 复杂隐藏代理(Complexity Hiding Proxy):用来隐藏一个类得复杂集合的复杂度,并进行控制访问,也称为外观代理(Facade Proxy)
  10. 写入时复制代理(Copy-On-Write Proxy):用来控制对象的复制,方法是延迟对象的复制,知道客户真的需要为止。是虚拟代理的变体。(java5,CopyOnWriteArrayList)
代理模式与装饰者(Decorator)模式区别
  1. 两者类图一样,但是目的不同,装饰者是为给对象增加行为,而代理模式是控制对对象的访问。
  2. 代理模式有时候会创建真实对象,装饰者模式不会创建被装饰的对象
  3. 代理不会讲一个主题包装多次,装饰者不做限制
使用方式

  • 一般使用工厂模式,实例化并返回代理对象

代码示例:
[java]  view plain copy
  1. /** 
  2.  * 代理与真正对象的共同接口 
  3.  * @author sky 
  4.  * 
  5.  */  
  6. public interface Subject {  
  7.   
  8.     public void doSomething();  
  9. }  
  10.   
  11. /** 
  12.  * 真正对象 
  13.  * @author sky 
  14.  * 
  15.  */  
  16. public class RealSubject implements Subject {  
  17.   
  18.     @Override  
  19.     public void doSomething() {  
  20.         System.out.println("真正对象的操作");  
  21.     }  
  22.   
  23. }  
  24.   
  25. /** 
  26.  * 代理类 
  27.  * @author sky 
  28.  * 
  29.  */  
  30. public class ProxySubject implements Subject {  
  31.       
  32.     private RealSubject subject;  
  33.       
  34.     public ProxySubject(){  
  35.         subject = new RealSubject();  
  36.     }  
  37.   
  38.     @Override  
  39.     public void doSomething() {  
  40.         System.out.println("代理对象添加功能");  
  41.         subject.doSomething();  
  42.         System.out.println("代理对象添加功能");  
  43.     }  
  44.   
  45. }  
  46.   
  47. /** 
  48.  * 测试类 
  49.  * @author sky 
  50.  * 
  51.  */  
  52. public class Test {  
  53.   
  54.     public static void main(String[] args) {  
  55.         ProxySubject subject = new ProxySubject();  
  56.         subject.doSomething();  
  57.     }  
  58.   
  59. }  
  60.   
  61. 输出:  
  62.     代理对象添加功能  
  63.     真正对象的操作  
  64.     代理对象添加功能  


动态代理
  JDK 5引入的动态代理机制,允许开发人员在运行时刻动态的创建出代理类及其对象。在运行时刻,可以动态创建出一个实现了多个接口的代理类。每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接 口的实现。当使用者调用了代理对象所代理的接口中的方法的时候,这个调用的信息会被传递给InvocationHandler的invoke方法。在 invoke方法的参数中可以获取到代理对象、方法对应的Method对象和调用的实际参数。invoke方法的返回值被返回给使用者。这种做法实际上相 当于对方法调用进行了拦截。
动态代理主要使用java.lang.reflect包下的InvocationHandler接口、Proxy类。InvocationHandler用来实现代理行为,Proxy用来创建代理类

代码示例:
[java]  view plain copy
  1.  /** 
  2.  * 切面接口 
  3.  * @author sky 
  4.  * 
  5.  */  
  6. public interface AopInterface {  
  7.   
  8.     public void addBefore(String str);  
  9.       
  10.     public void addEnd(String str);  
  11. }  
  12.   
  13. public class Aop implements AopInterface {  
  14.   
  15.     @Override  
  16.     public void addBefore(String str) {  
  17.         System.out.println(str+" 调用前");  
  18.     }  
  19.   
  20.     @Override  
  21.     public void addEnd(String str) {  
  22.         System.out.println(str+" 调用后");  
  23.     }  
  24.   
  25. }  
  26.   
  27. /** 
  28.  * 代理行为 
  29.  * @author sky 
  30.  * 
  31.  */  
  32. public class AopInvocationHandler implements InvocationHandler {  
  33.       
  34.     private AopInterface aop;  
  35.     private Object realObject;  
  36.       
  37.     public AopInvocationHandler(Object object){  
  38.         aop = new Aop();  
  39.         realObject = object;  
  40.     }  
  41.   
  42.     @Override  
  43.     public Object invoke(Object object, Method method, Object[] arg2)  
  44.             throws Throwable {  
  45. //      method.invoke(object, arg2); 使用object会照成死循环,不清楚有什么用  
  46.         aop.addBefore(realObject.getClass().getName()+"类的"+method.getName()+"方法");  
  47.         Object obj = method.invoke(realObject, arg2);  
  48.         aop.addEnd(realObject.getClass().getName()+"类的"+method.getName()+"方法");  
  49.         return obj;  
  50.     }  
  51.   
  52. }  
  53.   
  54. /** 
  55.  * 代理与真正对象的共同接口 
  56.  * @author sky 
  57.  * 
  58.  */  
  59. public interface Subject {  
  60.   
  61.     public void doSomething();  
  62. }  
  63.   
  64. /** 
  65.  * 真正对象 
  66.  * @author sky 
  67.  * 
  68.  */  
  69. public class RealSubject implements Subject {  
  70.   
  71.     @Override  
  72.     public void doSomething() {  
  73.         System.out.println("真正对象的操作");  
  74.     }  
  75.   
  76. }  
  77.   
  78. /** 
  79.  * 测试类 
  80.  * @author sky 
  81.  * 
  82.  */  
  83. public class Test {  
  84.       
  85.     public static void main(String[] args) {  
  86.         Subject subject = new RealSubject();  
  87.         Subject proxy = (Subject)Proxy.newProxyInstance(subject.getClass().getClassLoader(),   
  88.                 subject.getClass().getInterfaces(), new AopInvocationHandler(subject));  
  89.         proxy.doSomething();  
  90.     }  
  91.   
  92. }  
  93.   
  94. 输出:  
  95.     proxy.dynamic.RealSubject类的doSomething方法 调用前  
  96.     真正对象的操作  
  97.     proxy.dynamic.RealSubject类的doSomething方法 调用后  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值