简单的了解下代理模式
代理就是一个人或一个机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或不能够直接引用对象,而代理对象可以在客户端和目标对象之间起到中介作用
代理模式包括远程代理,虚拟代理,copy-on-write代理,保护代理,catch代理,防火墙代理,同步化代理,只能引用代理,这些我就不一一介绍,我只是用简单例子,了解什么是代理模式。
代理模式设计到的角色:
抽象主题角色:声明了真是主题和代理主题的公共接口,这样可以使用真实主题的地方都可以使用代理主题。
代理主题角色:代理主题角色内不含有真实主题的引用,从而可以在任何时刻操作真实主题对象,代理主题角色提供一个与真实主题相同的接口,可以在任何时刻替代真实主题控制真实主题引用,负责在需要的时候创建真实主题对象(和删除真实主题对象),代理角色通常再将客户端调用传递给真实主题之前,或之后,都执行谋个操作,而不是单纯的将调用传递给真实主题。
真实主题角色:定义了代理角色所代表的真实对象
根据例子看看:
abstract public class Subject { //定义抽象请求方法 abstract public void request(); }
真实主题
public class RealSubject extends Subject{ public RealSubject(){ } public void request() { // TODO Auto-generated method stub System.out.println("请求"); } }
代理主题
public class ProxySubject extends Subject{ private RealSubject realSubject; public ProxySubject(){ System.out.println("进入代理类......."); } @Override public void request() { // TODO Auto-generated method stub preRequest(); if(realSubject==null){ realSubject = new RealSubject(); } realSubject.request(); postRequest(); } /** * 请求前操作 * */ private void preRequest(){ System.out.println("请求前"); } /** * 请求后操作 * */ private void postRequest(){ System.out.println("请求后"); } }
测试代理
public class TestProxy { public static void main(String[] args) { Subject s = new ProxySubject(); s.request(); } }
代理模式的时序图。
从这个测试不难看出代理类的作用,代理主题并不改变主题接口,模式的用意是不让客户端感觉到代理的存在,其次,代理使用委派将客户端的调用委派给真实主题对象,代理主题起到的是一个传递作用;最后,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯的传递请求。
接下来说说动态代理模式
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<String> v = null; v = (List) VectorProxy.factory(new Vector(10)); v.add("New"); v.add("York"); } }
运行结果:
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
New
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
York
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
此例子用了反射,从结果可以看出代理对象截获了对Vector对象的所有调用,在调用传递给Vector之前和之后,代理对象具有采取合适操作的灵活性,虽然这里代理对象所采取的操作就是打印,也可以定义其他操作。