代理模式 PROXY Surrogate 结构型 设计模式
意图
为其他的对象提供一种代理以控制对这个对象的访问。
代理模式含义比较清晰,就是中间人,中介公司,经纪人...
在计算机程序中,代理就表示一个客户端不想或者不能够直接引用一个对象
而代理对象可以在客户端和目标对象之间起到中介的作用
结构
代理模式的根本在于隔离,如下图所示,间接访问
代理对象如何能够真的代理真实对象?
在Java语言中,看起来像的一个方式就是实现同一接口
代理角色和真实对象角色拥有共同的抽象类型,他们拥有相同的对外接口request()方法
ProxySubject内部拥有一个RealSubject
你应该能感觉到组合模式的思想-----他们都是Subject,属于同一个Component
对外有一致的接口
抽象主题角色Subject
声明了真实主题和代理主题的共同接口,任何使用真实主题的地方,都可以使用代理主题
代理主题角色ProxySubject
代理主题角色内部含有对真实对象的引用,从而可以在任何时候操作真实主题
代理主题提供与真实主题的相同的接口,以便任何时刻,都可以替代真实主题
而且,代理主题还可以在真实主题执行前后增加额外的处理,比如:经纪人要先收下费~
真实主题角色RealSubject
被代理的真实主题对象,真正工作的是他,比如经纪人总不会站在舞台上去~
示例代码
Subject 抽象角色 定义了真正的处理请求 的request()方法
package proxy; public interface Subject { void request(); }
RealSubject真实主题角色,实现了处理请求的方法
package proxy; public class RealSubject implements Subject { @Override public void request() { System.out.println("realSubject process request...."); } }
Proxy代理角色
实现了request()方法,用于替代真实主题,内部调用真实主题完成请求
并且额外的提供了pre和after操作
package proxy; public class Proxy implements Subject{ private Subject realSubject; @Override public void request() { preRequest(); realSubject.request(); afterRequest(); } public Proxy(Subject realSubject){ this.realSubject = realSubject; } public void preRequest(){ System.out.println("pre request do sth...."); } public void afterRequest(){ System.out.println("after request do sth...."); } }
测试类
package proxy; public class Test { /**请求subject执行请求 * @param subject */ public static void askForSth(Subject subject){ subject.request(); System.out.println("################"); } public static void main(String[] args){ Subject real = new RealSubject(); Subject proxy = new Proxy(real); askForSth(proxy); askForSth(real); } }
定义了真实对象,也定义了一个代理对象
查看他们分别处理请求的结果
从下面的时序图中,能更好的感受到“间接”的感觉
在真正调用真实对象方法前,需要先执行preRequest方法