zoukankan      html  css  js  c++  java
  • 结构模式--之--代理模式

    代理模式是对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
    按照使用目的来划分,代理有以下几种:
    1.远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。优点 是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的,而不是远程的而代理对象承担了大部分的网络通信工作。缺点是客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。
    2.虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的时候,虚拟代理的优点就非常明显。
    3.Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
    4.保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限
    5.Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
    6.防火墙(Firewall)代理:保护目标,不让恶意用户接近
    7.同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
    8.智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
      在所有种类的代理模式中,虚拟代理,远程代理,智能引用代理和保持代理是最为常见的代理模式。
     
    代理模式的角色有:
    1.抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以使用代理主题。
    2.代理主题(Proxy)角色:代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象,代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体,控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象),代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯地将调用传递给真实主题对象。
    3.真实主题角色:定义了代理角色所代表的真实对象。
    示例性代码如下:
     1 public class ProxyTest {
     2     public static void main(String[] args) {
     3         Subject subject = new ProxySubject();
     4         subject.request();
     5     }
     6 }
     7 
     8 
     9 //抽象主题角色
    10 abstract class Subject{
    11     //抽象请求方法
    12     abstract public void request();
    13 }
    14 
    15 //具体角色
    16 class RealSubject extends Subject{
    17     //实现真实的请求方法
    18     @Override
    19     public void request() {
    20         System.out.println("From real subject");
    21     }
    22     
    23 }
    24 
    25 //代理角色,它除了将所有的请求原封不动地委派给真实主题角色外,还在委派前和后执行了一些操作
    26 class ProxySubject extends Subject{
    27     
    28     private RealSubject realSubject;
    29     
    30     //请求方法
    31     @Override
    32     public void request() {
    33         preRequest();
    34         if(null == realSubject){
    35             realSubject = new RealSubject();
    36         }
    37         realSubject.request();
    38         postRequest();
    39     }
    40     //请求前
    41     public void preRequest(){
    42         System.out.println("Before Request");
    43     }
    44     //请求后
    45     public void postRequest(){
    46         System.out.println("After Request");
    47     }
    48 }
    从JDK3后,Java语言通过在java.lang.reflect库中提供下面三个类直接支持代理模式:Proxy,InvocationHandler和Method.其中Proxy类使得设计师能够在运行时间创建代理对象,当系统有了一个代理对象后,对原对象的方法调用会首先被分派给一个调用处理处理器(InvocationHandler).程序可以在调用处理器invoke()方法中截获这个调用,进行额外的操作。显然Java所提供的这一支持是建立在反射之上的。
    设计师可以按以下步骤创建动态代理对象
    1.指明一系列的接口来创建一个代理对象
    2.创建一个调用处理器(InvocationHandler)对象
    3.将这个代理指定为某个其他对象的代理对象
    4.在调用处理器的invoke()方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要做的操作。
     
     
     
    以下以一个例子来说明使用动态代理:为一个Vector对象提供一个代理对象,当Vector的任何方法被调用之前和调用之后,分别打印出两条信息,这表明代理对象能能力截获和控制这个Vector对像
     1 public class DynamicProxy {
     2     public static void main(String[] args) throws Exception{
     3         
     4         List list= (List)VectorProxy.factory(new Vector());        
     5         list.add("one");
     6         list.add("two");
     7         
     8     }
     9 }
    10 
    11 class VectorProxy implements InvocationHandler{
    12     
    13     private Object proxyobj;
    14     
    15     public VectorProxy(Object obj){
    16         this.proxyobj = obj;
    17     }
    18     
    19     //调用某个方法
    20     @Override
    21     public Object invoke(Object proxy, Method method, Object[] args)
    22             throws Throwable {
    23         System.out.println("Before calling"+method);
    24         Object o = method.invoke(proxyobj, args);
    25         System.out.println("After calling"+method);
    26         return o;
    27     }
    28     public static Object factory(Object obj) throws Exception{
    29         Class cls = obj.getClass();
    30         return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),new VectorProxy(obj));
    31         
    32     }
    33 }
  • 相关阅读:
    最大子数组问题(分治策略实现)
    Solving the Detached Many-to-Many Problem with the Entity Framework
    Working With Entity Framework Detached Objects
    Attaching detached POCO to EF DbContext
    如何获取qq空间最近访问人列表
    Health Monitoring in ASP.NET 2.0
    problem with displaying the markers on Google maps
    WebMatrix Database.Open… Close() and Dispose()
    Accessing and Updating Data in ASP.NET: Retrieving XML Data with XmlDataSource Control
    Create web setup project that has crystal reports and sql script run manually on client system
  • 原文地址:https://www.cnblogs.com/wn398/p/3230244.html
Copyright © 2011-2022 走看看