Proxy模式,为其他对象提供一种代理,并以控制对这个对象的访问。(Provide asurrogate or placeholder foranother objecttocontrol access to it. )而对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化。它是给某一个对象提供一个替代者(占位者),使之在client对象和subject对象之间编码更有效率。代理可以提供延迟实例化(lazy instantiation),控制访问, 等等,包括只在调用中传递。一个处理纯本地资源的代理有时被称作虚拟代理。远程服务的代理常常称为远程代理。强制控制访问的代理称为保护代理。
应用场景
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一些可以使用Proxy模式常见情况:
1)远程代理(Remote Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
2)虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
3)保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4)智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
5)Copy-on-Write代理它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
模式架构
1)代理角色(Proxy):
保存一个引用使得代理可以访问实体。若 RealSubject和Subject的接口相同,Proxy会引用Subject。提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。控制对实体的存取,并可能负责创建和删除它。
其他功能依赖于代理的类型:
• Remote Proxy负责对请求及其参数进行编码,并向不同地址空间中的实体发送已编码的请求。
• Virtual Proxy可以缓存实体的附加信息,以便延迟对它的访问。
• Protection Proxy检查调用者是否具有实现一个请求所必需的访问权限。
2) 抽象主题角色(Subject):定义真实主题角色RealSubject
和抽象主题角色Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。代理主题通过持有真实主题RealSubject的引用,不但可以控制真实主题RealSubject的创建或删除,可以在真实主题RealSubject被调用前进行拦截,或在调用后进行某些操作。
3) 真实主题角色(RealSubject):定义了代理角色(proxy)所代表的具体对象.
在调用RealSubject的request()之前,Proxy物件也许会有一些预先处理的操作,就假设我们组织为preOperation()与 postOperation()好了,当客户对Proxy发出request()请求后,一个可能的时序图如下所示:
您的preOperation()与postOperation()正决定了Proxy模式使用于何种情况,例如一个Remote Proxy的情况,可以为一个远端真实物件提供一个局部代表;Protection Proxy控制对物件的访问,您可以使用它来作不同级别、权限的存取控制;Cache Proxy为一个物件提供临时的储存,使得许多客户端都能直接存取它,而不用对真实物件直接要求,只有在必要的时候更新这个临时物件,或是让客户直接存取真实物件。
代码实现
新建一个买车的接口:
public interface buy_car {
}
新建一个people人类,具有买车的行为,所以实现接口buy_car
classpeople implements buy_car {
public int getCash(){
}
people类不能拥有车,必须经过proxy代理类的认证,符合条件之后才可以拥有车辆,新建一个代理,这个代理类来考察当前的people是否有资格进行买车:
classproxyclass implements buy_car {
}
最后创建一个客户端,用来模拟买车的行为:
publicclass run_main {
}
程序运行结果如下: