为一个对象提供另一个替身或者占位符以控住这个对象的访问。

  • 各种代理的共同点:都会将客户端对主题施加的方法调用拦截下来。
  • 创建代表,让代表对象控制某对象的访问,被代理的对象可以是远程对象、创建开销大的对象、需要安全控制的对象等等。
  • 代理模式建议新建一个与原服务对象接口相同的代理类, 然后更新应用以将代理对象传递给所有原始对象客户端。 代理模式 - 图1
  • 代理类接收到客户端请求后会创建实际的服务对象, 并将所有工作委派给它。

代理模式 - 图2
代理将自己伪装成数据库对象, 可在客户端或实际数据库对象不知情的情况下处理延迟初始化和缓存查询结果的工作。

  1. 服务接口 (Service Interface) 声明了服务接口。 代理必须遵循该接口才能伪装成服务对象。
  2. 服务 (Service) 类提供了一些实用的业务逻辑。
  3. 代理 (Proxy) 类包含一个指向服务对象的引用成员变量。 代理完成其任务 (例如延迟初始化、 记录日志、 访问控制和缓存等) 后会将请求传递给服务对象。 通常情况下, 代理会对其服务对象的整个生命周期进行管理。
  4. 客户端 (Client) 能通过同一接口与服务或代理进行交互, 所以你可在一切需要服务对象的代码中使用代理。

实例

本例演示如何使用代理模式在第三方腾讯视频 (TencentVideo, 代码示例中记为 TV) 程序库中添加延迟初始化和缓存。
代理模式 - 图3
使用代理缓冲服务结果。
程序库提供了视频下载类。 但是该类的效率非常低。 如果客户端程序多次请求同一视频, 程序库会反复下载该视频, 而不会将首次下载的文件缓存下来复用。

代理类实现和原下载器相同的接口, 并将所有工作委派给原下载器。 不过, 代理类会保存所有的文件下载记录, 如果程序多次请求同一文件, 它会返回缓存的文件。

image.png

对比

适配器模式能为被封装对象提供不同的接口, 代理模式能为对象提供相同的接口, 装饰模式则能为对象提供加强的接口。

装饰器增加行为,代理是控制对象的访问。
适配器改变接口,代理是想相同的接口。