一、代理模式的结构
代理模式给某一个对象提供一个代理对象,并有代理对象控制对原对象的引用。按照使用目的来划分有以下几种:
远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使。
虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
防火墙(Firewall)代理:保护目标,不让恶意用户接近。
同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如:将对此对象调用的次数记录下来等。
其结构图如下:
二、代理模式在java中的应用
Java的动态代理
在java.lang.reflect库中提供下面三个类直接支持代理模式:Proxy,InvocationHandler,Method。可以按照下面步骤创建动态代理对象:
1、指明一系列的接口来创建一个代理对象。
2、创建一个调用处理器(Invocation Handler)对象。
3、将这个代理制定为某个其他对象的代理对象。
4、在调用处理器的invoke()方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要做的操作。
例如:
- import java.awt.List;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.Vector;
- 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 0;
- }
- public static void main(String []args){
- List v = null;
- v = (List)factory(new Vector(10));
- v.add("New");
- v.add("York");
- }
- }
三、代理模式与其他模式的关系
适配器模式
适配器模式与代理模式很相像,他们都可视为一个对象提供一种前置的接口。适配器模式的用意是要改变所考虑的对象接口,而代理模式并不能改变所代理的对象的接口。
装饰模式
装饰模式与所装饰的对象具有相同的接口,因此这两种模式也有可能混淆。但是,装饰模式应当为所装饰的对象提供增强功能;而代理模式对对象的使用施加控制,并不提供对象本身的增强功能。