代理模式

对象结构型模式

模式动机

有时候,一个客户不想或者无法直接引用一个对象,此时可以通过一个“代理”作为第三者进行间接引用。通过代理对象可以去掉客户不能看到的内容或者添加客户需要的额外服务。

通过引入一个新对象(比如远程代理对象),实现对真实对象的操作或者将新对象作为真实对象的替身,间接访问真实对象。

应用

代理模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

代理模式包含如下角色:

  • 抽象主题角色Subject
  • 代理主题角色Proxy
  • 真实主题角色RealSubject

代理模式的示意图可以简化成如下形式:

典型代码类实现代码:

public class Proxy implements Subject {
private RealSubject realSubject = new RealSubject();
public void preRequest() {
// ...
}
public void request() {
preRequest();
realSubject.request();
postRequest();
}
public void postRequest() {
// ...
}
}

实例:论坛权限控制代理

在一个论坛中已注册用户和游客的权限不同,已注册的用户拥有发帖、修改自己的注册信息、修改自己的帖子等功能;而游客只能看到别人发的帖子,没有其他权限。此处使用代理模式中的保护代理,该代理用于控制对一个对象的访问,可以给不同用户提供不同权限。

实例:本地设置远程代理

模拟应用远程代理来访问另外一个应用程序域中的对象,如果在远程实现了加减乘除等运算,在本地需要调用,那么可以考虑在本地设置一个代理。

优点

  1. 协调调用者和被调用者,一定程度上降低耦合
  2. 远程代理使客户端可以访问远程机器上的对象
  3. 虚拟代理通过使用一个小对象来代表大对象,减少系统资源消耗,提高运行速度
  4. 保护代理可以控制用户权限

缺点

  1. 代理在其中多套了一层,可能导致请求处理速度变慢
  2. 增加系统实现难度

适用场合

需要用到代理的系统,常见的代理有如下几种:

  • 远程代理:为一个位于不同地址空间的对象提供一个本地的代理对象,远程代理又叫做大使(Ambassador)

  • 虚拟代理:需要创建一个资源消耗大的对象,先创建一个消耗相对小的对象,真实对象只有在需要时才创建

  • Copy-on-Write代理:虚拟代理的一种,把copy操作延迟到只有在客户端真正需要时才执行。一般用于深拷贝,因为深拷贝很耗时,所以只有深拷贝的对象要被用到时才真正去执行深拷贝(自然一直用不到的话就不会深拷贝了)

  • 保护代理:控制对一个对象的访问,可以给用户分配不同权限

  • 缓冲代理:为某一个目标操作提供临时存储空间,以便多个客户端可以共享结果

  • 防火墙代理:阻止恶意用户

  • 智能引用代理:当一个对象被引用/调用方法时,代理提供一些额外操作(周边业务),比如记录此次调用/记录总被调用次数

Java RMI(远程方法调用)就是典型的远程代理模式

(•‿•)