结构型模式之代理模式
一.定义
代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。
二、模式结构成员构成
• Subject: 抽象主题角色
• Proxy: 代理主题角色
• RealSubject: 真实主题角色
三.代码示例
1)静态代理
View Code
1 /** 2 * Subject 3 * 抽象角色 4 */ 5 public abstract class Subject { 6 public abstract void request(); 7 } 8 9 10 /** 11 * RealSubject 12 * 真实的角色 13 */ 14 public class RealSubject extends Subject { 15 16 @Override 17 public void request() { 18 // TODO Auto-generated method stub 19 20 } 21 } 22 23 24 /** 25 * Proxy 26 * 静态代理,对具体真实对象直接引用 27 * 代理角色,代理角色需要有对真实角色的引用, 28 * 代理做真实角色想做的事情 29 */ 30 public class ProxySubject extends Subject { 31 32 private RealSubject realSubject = null; 33 34 /** 35 * 除了代理真实角色做该做的事情,代理角色也可以提供附加操作, 36 * 如:preRequest()和postRequest() 37 */ 38 @Override 39 public void request() { 40 preRequest(); //真实角色操作前的附加操作 41 42 if(realSubject == null){ 43 realSubject = new RealSubject(); 44 } 45 realSubject.request(); 46 47 postRequest(); //真实角色操作后的附加操作 48 } 49 50 /** 51 * 真实角色操作前的附加操作 52 */ 53 private void postRequest() { 54 // TODO Auto-generated method stub 55 56 } 57 58 /** 59 * 真实角色操作后的附加操作 60 */ 61 private void preRequest() { 62 // TODO Auto-generated method stub 63 64 } 65 66 } 67 68 /** 69 * client 70 */ 71 public class Client { 72 73 74 public static void main(String[] args) { 75 Subject subject = new ProxySubject(); 76 subject.request(); //代理者代替真实者做事情 77 } 78 79 }
2) 动态代理
1 /** 2 * Subject 3 * 抽象角色 4 */ 5 public abstract class Subject { 6 public abstract void request(); 7 } 8 9 /** 10 * RealSubject 11 * 真实的角色 12 */ 13 public class RealSubject extends Subject { 14 15 @Override 16 public void request() { 17 // TODO Auto-generated method stub 18 19 } 20 } 21 22 /** 23 * proxy 24 * 动态代理, 它是在运行时生成的class,在生成它时你必须提供一组interface给它, 然后该class就宣称它实现了这些interface。 25 * 你当然可以把该class的实例当作这些interface中的任何一个来用。 当然啦,这个Dynamic 26 * Proxy其实就是一个Proxy,它不会替你作实质性的工作, 在生成它的实例时你必须提供一个handler,由它接管实际的工作。 27 */ 28 public class DynamicSubject implements InvocationHandler { 29 30 private Object sub; // 真实对象的引用 31 32 public DynamicSubject(Object sub) { 33 this.sub = sub; 34 } 35 36 @Override 37 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 38 System.out.println("before calling " + method); 39 method.invoke(sub, args); 40 System.out.println("after calling " + method); 41 return null; 42 } 43 44 } 45 46 /** 47 * client 48 */ 49 public class Client { 50 51 public static void main(String[] args) throws Throwable { 52 RealSubject rs = new RealSubject(); 53 InvocationHandler handler = new DynamicSubject(rs); 54 Class cls = rs.getClass(); 55 //以下是分解步骤 56 /* 57 Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces()); 58 Constructor ct = c.getConstructor(new Class[]{InvocationHandler.class}); 59 Subject subject =(Subject) ct.newInstance(new Object[]{handler}); 60 */ 61 62 //以下是一次性生成 63 Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(), handler); 64 subject.request(); 65 } 66 }
四.优点和缺点分析
优点:
> 代理模式能够协调调用者和被调用者,在一定程度上降低了系 统的耦合度。
> 代理模式能够增强被调用者的功能,让被调用者在原有功能上,增加其他额外的功能。
缺点:
>实现代理模式需要额外的工作,有些代理模式的实现 非常复杂。
五.应用场景
>为某个对象提供额外的操作的时候
你投入得越多,就能得到越多得价值