定义
为其他对象提供一种代理以控制对这个对象的访问。
结构和说明
示例代码
public class ProxyDemo {
/**
* 抽象的目标接口,定义具体的目标对象和代理公用的接口
*/
public static interface Subject {
/**
* 示意方法: 一个抽象的请求方法
*/
void request();
}
/**
* 具体的目标对象,是真正被代理的对象
*/
public static class RealSubject implements Subject {
@Override
public void request() {
// 执行具体的功能处理
}
}
/**
* 代理对象
*/
public static class Proxy implements Subject {
/**
* 持有被代理的具体的目标对象
*/
private RealSubject realSubject;
/**
* 构造方法,传入被代理的具体的目标对象
*
* @param realSubject 被代理的具体的目标对象
*/
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
// 在转调具体的目标对象前,可以执行一些功能处理
realSubject.request();
// 在转调具体的目标对象后,可以执行一些功能处理
}
}
public static class Client {
public static void main(String[] args) {
Subject subject = new Proxy(new RealSubject());
subject.request();
}
}
}
调用顺序
特点
代理模式在客户和被客户访问的对象之间,引入了一定程度的间接性,客户是直接使用代理,让代理来与被访问的对象进行交互。不同的代理类型,这种附加的间接性有不同的用途,也就具有不同的特点。
- 远程代理: 隐藏了一个对象存在与不同地址空间的事实,也即是客户通过远程代理去访问一个对象,根本不关心这个对象在哪里,也不关心如何通过网络去访问到这个对象。从客户的角度来讲,它只是在使用代理对象而已。
- 虚代理: 可以根据需要来创建“大”对象,只有到必须创建对象的时候,虚代理才会创建对象,从而大大加快程序运行速度,并节省资源。通过虚代理可以对系统进行优化。
- 保护代理: 可以在访问一个对象前后,执行很多附加的操作,除了进行权限监控之外,还可以进行很多跟业务相关的处理,而不需要修改被处理的对象。也就是说,可以通过代理来给目标对象增加功能。
- 智能指引: 和保护代理类似,也是允许在访问一个对象前后,执行很多附加操作,这样一来就可以做很多额外的事情,比如引用计数等。
思考
本质
控制对象访问。
何时选用
- 需要为一个对象在不同地址空间提供局部代表的时候,可以使用远程代理。
- 需要按照需要创建开销很大的对象的时候,可以使用虚代理。
- 需要控制对原始对象的访问的时候,可以使用保护代理。
- 需要在访问对象执行一些附加操作的时候,可以使用智能指引代理。
相关模式
- 代理和适配器模式
这两个模式有一定的相似性,但也有差异。
这个两个模式有相似性,他们都为另外一个对象提供间接性的访问,而且都是从自身以外的一个接口向这个对象转发请求。
但是从功能上,这个两个模式是不一样的。适配器模式主要用来解决接口之间不匹配的问题,它通常是为所适配的对象提供一个不同的接口;而代理模式会实现和目标对象相同的接口。
- 代理和装饰模式
这两个模式从实现上相似,但是功能上是不同的。
装饰模式的实现和保护代理的实现是类似的,都是在转调其他对象的前后执行一定的功能。但是他们的目的和功能都是不同的。
装饰模式的目的是为了让你不生成子类就可以给兑现添加职责,也就是为了动态地增加功能;而代理模式的主要目的是控制对对象的访问。