首页 > 代码库 > 代理(Proxy)模式

代理(Proxy)模式

  代理模式的类图如下所示:

      

     客户端想调用的是RealSubject,由于某种考虑或原因,只能直接访问到ProxySubject,再由ProxySubject去调用RealSubject,这就完成了一次代理的活动。

     代理模式的时序图如下:

     

      从上面可以看出,ProxySubject不仅可以完成对RealSubject的调用,在调用前后还可以完成一些事情,这就是代理模式的优点。

 

      代理模式按照使用的分类,可以分为以下几类:

      远程代理:为一个不同地址空间的对象提供一个局域代表对象。

      虚拟代理:根据需求创建一个资源消耗较大的对象,使得对象在使用时才被真正地使用。

      Copy-on-Write代理:虚拟代理的一种,把复制行为推迟到真正需要时再去执行。

      保护代理:控制对一个对象的访问,可以对不同用户提供不同权限。

      Cache代理:为某一目标的操作结果提供临时的存储空间,使得多个客户端可以共享这些结果。

      同步化代理:使得多个用户同时使用一个目标而没有冲突。

      智能引用代理:引用一个对象时提供一些额外的操作,如记录被调用的次数等。

 

     Java类库中有三个类直接支持代理模式:Proxy,InvocationHandler和Method。

     下面是在List加上代理,在添加元素的前后打印一些信息。     

public class VectorProxy implements InvocationHandler{    private Object proxyobj;    public VectorProxy(Object obj){        proxyobj = obj;    }	public static Object factory(Object obj){		Class cls = obj.getClass();        return Proxy.newProxyInstance( cls.getClassLoader(),            cls.getInterfaces(),            new VectorProxy(obj) );    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{		System.out.println("before calling " + method);        if (args != null){			for (int i=0; i<args.length; i++){                System.out.println(args[i] + "");            }		}        Object o = method.invoke(proxyobj, args);		System.out.println("after calling " + method);        return o;    }    public static void main(String[] args){		List v = null;        v = (List) factory(new Vector(10));        v.add("New");        v.add("York");    }}

  打印出的信息如下:

before calling public abstract boolean java.util.List.add(java.lang.Object)Newafter calling public abstract boolean java.util.List.add(java.lang.Object)before calling public abstract boolean java.util.List.add(java.lang.Object)Yorkafter calling public abstract boolean java.util.List.add(java.lang.Object)

  

 

代理(Proxy)模式