一、模式动机
一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务。如在网页上查看一张图片,由于网速等原因图片不能立即显示,我们可以在图片传输过程中先把一些简单的用于描述图片的文字传输到客户端,此时这些文字就成为了图片的代理。
二、模式定义
代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate。代理模式是一种对象结构型模式。
三、模式结构
四、参与者
抽象主题角色(Subject)
声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题真实主题(RealSubject)角色
定义了代理角色所代表的真实对象代理主题(Proxy)角色
- 代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;
- 代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题;
- 控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象)
五、示例代码
package design.pattern;
// 快递工作人员
class ExpressPerson {
private String name;
public ExpressPerson(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// 寄东西
interface GiveObject {
void giveComputer();
void giveBaggage();
}
// 毕业生
class Graduate implements GiveObject {
ExpressPerson ydy;
public Graduate(ExpressPerson ydy) {
this.ydy = ydy;
}
public void giveComputer() {
System.out.println(ydy.getName() + "请你托运计算机");
}
public void giveBaggage() {
System.out.println(ydy.getName() + "请你托运行李");
}
}
// 女同学
class Classmate implements GiveObject {
Graduate zhangsan;
public Classmate(ExpressPerson ydy) {
zhangsan = new Graduate(ydy);
}
public void giveComputer() {
zhangsan.giveComputer();
}
public void giveBaggage() {
zhangsan.giveBaggage();
}
}
public class Proxy {
public static void main(String[] args) {
ExpressPerson ydy = new ExpressPerson("宅急送");
Classmate girl = new Classmate(ydy);
girl.giveComputer();
girl.giveBaggage();
}
}
模式结构
模式使用
远程(Remote)代理
为一个位于不同的地址空间的对象提供一个局域代表对象。可以隐藏一个对象存在于不同地址空间的事实。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。虚拟(Virtual)代理
代理对象可以在必要的时候才将被代理的对象加载。代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的时候,虚拟代理的优点就非常明显。保护(Protect or Access)代理
可以在运行时对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。缓冲(Cache)代理
为那些昂贵操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。防火墙(Firewall)代理
保护目标,不让恶意用户接近。同步化(Synchronization)代理
使几个用户能够同时访问目标对象而没有冲突。智能引用(Smart Reference)代理
当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。写时复制(Copy-on-Write)代理
虚拟代理的一种。把复制 (克隆)拖延到只有在客户端需要时,才真正采取行动。
优点
- 代理模式能够协调调用者和被调用者,能够在一定程度上降低系统的耦合度。
- 当对象在远程机器上,要通过网络来生成时速度可能会很慢,此时应用代理模式可以掩盖对象在网络上生成的过程,系统的速度会加快。
- 对于大对象的加载(如大图片),虚拟代理可以让加载过程在后台执行,前台使用的代理对象会使得整体运行速度得到优化。
缺点
- 请求的处理速度会变慢,并且实现代理模式需要额外的工作。