漫说代理模式---给宝宝成长护航

  1. 宝宝还很小,外面的世界可不安全,如今宝宝的护航者宝宝的监护人爸爸妈妈闪亮登场。

漫说代理模式---给宝宝成长护航

2,监护过程:有了监护人,宝宝就比较安全了,若是谁想和宝宝一块儿玩就须要先找到监护人,通过监护人赞成才能够和宝宝一块儿玩。html

漫说代理模式---给宝宝成长护航

还好比过年了,宝宝收到不少压岁钱,须要把钱存到银行,就须要父母帮忙才能够。java

  1. 上面就用到了代理模式。

As described by GoF:缓存

"Provide a surrogate or placeholder for another object to control access over it."

UML图以下所示:安全

漫说代理模式---给宝宝成长护航

1)代理角色(Proxy):
. 保存一个引用使得代理能够访问实体。若 RealSubject和Subject的接口相同,Proxy会引用Subject。
. 提供一个与Subject的接口相同的接口,这样代理就能够用来替代实体。
. 控制对实体的存取,并可能负责建立和删除它。
. 其余功能依赖于代理的类型:
• Remote Proxy负责对请求及其参数进行编码,并向不一样地址空间中的实体发送已编码的请求。
• Virtual Proxy能够缓存实体的附加信息,以便延迟对它的访问。
• Protection Proxy检查调用者是否具备实现一个请求所必需的访问权限。
2) 抽象主题角色(Subject):定义真实主题角色RealSubject 和 抽象主题角色Proxy的共用接口,这样就在任何使用RealSubject的地方均可以使
用Proxy。代理主题经过持有真实主题RealSubject的引用,不但能够控制真实主题RealSubject的建立或删除,能够在真实主题RealSubject被调用前进行拦截,或在调用后进行某些操做. ide

3) 真实主题角色(RealSubject):定义了代理角色(proxy)所表明的具体对象. 性能

  1. 代理模式的应用场景

1) Remote Proxy能够隐藏一个对象存在于不一样地址空间的事实。也使得客户端能够访问在远程机器上的对象,远程机器可能具备更好的计算性能与处理速度,能够快速响应并处理客户端请求。
2) Virtual Proxy 能够进行最优化,例如根据要求建立对象。即经过使用一个小对象来表明一个大对象,能够减小系统资源的消耗。
3) Protection Proxies和Smart Reference都容许在访问一个对象时有一些附加的内务处理(Housekeeping task) 。优化

Proxy模式还能够对用户隐藏另外一种称之为写时复制(copy-on-write)的优化方式,该优化与根据须要建立对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操做,若是这个拷贝根本没有被修改,那么这些开销就没有必要。用代理延迟这一拷贝过程,咱们能够保证只有当这个对象被修改的时候才对它进行拷贝。在实现copy-on-write时必须对实体进行引用计数。拷贝代理仅会增长引用计数。只有当用户请求一个修改该实体的操做时,代理才会真正的拷贝它。在这种状况下,代理还必须减
少实体的引用计数。当引用的数目为零时,这个实体将被删除。copy-on-write能够大幅度的下降拷贝庞大实体时的开销。ui

代理模式可以协调调用者和被调用者,在必定程度上下降了系统的耦合度。this

代理模式的缺点

因为在客户端和真实主题之间增长了代理对象,所以有些类型的代理模式可能会形成请求的处理速度变慢。
实现代理模式须要额外的工做,有些代理模式的实现很是复杂。编码

  1. 示例程序:

    JDK proxies

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface AnInterface {
   public void doSomething();
}
class AClass implements AnInterface {
   public void doSomething() {
      System.out.println("Inside Method AClass.doSomething()");
   }
}
public class Test {
   public static void main(String args[]) {
      AnInterface realSubject = new AClass();
      AnInterface proxy = (AnInterface)Proxy.newProxyInstance(
                        realSubject.getClass().getClassLoader(),
                        realSubject.getClass().getInterfaces(),
                        new SimpleInvocationHandler(realSubject));
      passMeAProxy(proxy);
   }
   private static void passMeAProxy(AnInterface anInterface) {
      anInterface.doSomething();
   }
}
class SimpleInvocationHandler implements InvocationHandler {
   public SimpleInvocationHandler(Object realSubject) {
      this.realSubject = realSubject;
   }
   public Object invoke(Object proxy, Method m, Object[] args){
      Object result = null;
      System.out.println("Before Calling " + m.getName());
      try {
         result = m.invoke(realSubject, args);   
      }
      catch(Exception ex) {
         System.exit(1);
      }
      System.out.println("After Calling " + m.getName());
      return result;
   }
   private Object realSubject = null;
}

参考资料 :

http://www.oodesign.com/proxy-pattern.html

http://www.javaworld.com/article/2074068/learn-java/take-control-with-the-proxy-design-pattern.html?page=2

http://blog.csdn.net/hguisu/article/details/7542143

相关文章
相关标签/搜索