Java设计模式-代理模式之静态代理
概念
为另一个对象提供一个替身或占位符以提供对这个对象的访问,使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理对象可以是远程的对象、创建开销大的对象或需要安全控制的对象
- 远程代理控制访问远程对象
- 虚拟代理控制访问创建开销大的资源
- 保护代理基于权限控制对资源的访问 看如下的类图:
仔细看上面的类图,首先是Subject它为RealSubject和Proxy提供了接口,通过实现同一个接口,Proxy在RealSubject出现的地方取代它,这点和 适配器模式有比较大的区别。RealSubject是真正做事情的对象,它被proxy代理控制访问的对象,Proxy持有RealSubject的引用,在某些例子中Proxy还会负责RealSubject对象的创建和销毁。客户和RealSubject的交互都必须通过Proxy。因为Proxy和RealSubject实现了相同的接口Subject,所以任何用到RealSubject的地方,都可以用Proxy代替。Proxy也控制了对RealSubject的访问,在某些情况下面,我们可能需要:权限保护,远程访问,创建开销控制。
代理模式分类
代理模式分为 - 静态代理
- 由程序员创建或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。上面的类图很好的表示了这种关系,
- 动态代理
- 在程序运行时运用反射机制动态创建而成。动态代理在代理ProxySubject和RealSubject之间增加了InvocationHandler这一层,这是一种通信间接化,增加了灵 性性,将会在下一篇中介绍 动态代理
一个关于静态代理的例子
警匪片大家一定都不会陌生,一些有钱的人看那个不顺眼,就想着找黑帮的帮忙杀人,黑帮就帮他们做一些坏事。这里的老板就变成了RealSubject,黑帮就变成了(Proxy),这里的real和proxy只是针对杀人是谁指使的(即幕后黑手是那个)- 首先定义一个共同的接口,使得RealSubject出现的地方Proxy都可以出现
package ProxyMode; /* * 抽象接口,对应类图中的Subject * */ public interface Subject { public void SujectShow(); }
- 然后定义一个RealSubject,真正的幕后黑手
package ProxyMode; public class RealSubject implements Subject{ @Override public void SujectShow() { // TODO Auto-generated method stub System.out.println("杀人是我指使的,我是幕后黑手!By---"+getClass()); } }
- 然后定义一个代理类,黑帮,拿钱办事,但不是幕后黑手
package ProxyMode; import proxy.RealeSubject; public class ProxySubject implements Subject{ private Subject realSubject;//代理类中有 老板的引用。 public Subject TakeCall() //通过电话联系 { return new RealSubject(); } public void Before() { System.out.println("我只是一个代理类,在做事情之前我先声明,接下来的事情跟我无关,我只是受人指使!By---"+getClass()); } public void After() { System.out.println("正如事情还没有发生之前讲的一样,我只是个路人,上面做的事情跟我无关,我是受人指使的! By---"+getClass()); } @Override public void SujectShow() { // TODO Auto-generated method stub Object o=TakeCall(); //代理类接到了一个电话 if(checked(o)) //检查这个电话是不是老板打过来的 { Before(); this.realSubject=(Subject)o; realSubject.SujectShow(); After(); } else { System.out.println("不好意思,你权限不够,我帮不了你!"); } } boolean checked(Object o) //权限检查,这年头不是谁都可以冒充老板的 { if(o instanceof RealSubject ) return true; return false; } }
- 测试
package ProxyMode; public class ProxyTest { public static void main(String[] args) { ProxySubject proxy=new ProxySubject(); proxy.SujectShow(); } }
执行结果:
我只是一个代理类,在做事情之前我先声明,接下来的事情跟我无关,我只是受人指使!By---class ProxyMode.ProxySubject 杀人是我指使的,我是幕后黑手!By---class ProxyMode.RealSubject 正如事情还没有发生之前讲的一样,我只是个路人,上面做的事情跟我无关,我是受人指使的! By---class ProxyMode.ProxySubject