本博客大部分内容来于免费在线学习设计模式

1:代理模式(Proxy)

代理模式是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于目标对象的访问,并允许在将请求提交给对象前后进行一些处理。

2:代理模式问题

为什么要控制对于某个对象的访问呢?举个例子:有这样一个消耗大量系统资源的巨型对象,你只是偶尔需要使用它,并非总是需要。

20200816161130

或者给对象添加功能:在理想情况下,我们希望将代码直接放入对象的类中进行修改,但这并非总是能实现:比如类可能是第三方封闭库的一部分。所以我们也需要代理对象来添加功能

3:代理模式解决方案

代理模式建议新建一个与原目标对象接口相同的代理类,然后更新应用以将代理对象传递给所有原始对象客户端。代理类接收到客户端请求后会创建实际的目标对象,并将所有工作委派给它。

20200816161157

这有什么好处呢?

  • 如果需要在类的主要业务逻辑前后执行一些工作,你无需修改类就能完成这项工作。
  • 由于代理实现的接口与原类相同,因此你可将其传递给任何一个使用实际服务对象的客户端。

例:

信用卡是银行账户的代理,银行账户则是一大捆现金的代理。它们都实现了同样的接口,均可用于进行支付。
你通过信用卡操作银行帐户,然后进行转账等操作完成支付。不需要携带一大笔现金来完成支付。
又例如支付完成后,银行发的通知短信,这是对现金操作添加的额外功能。

4:代理模式结构

20200816161253

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

代码示例

5:代理模式适用场景

  1. 延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式。
    • 你无需在程序启动时就创建该对象,可将对象的初始化延迟到真正有需要的时候。
  2. 访问控制(保护代理)。如果你只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序(包括恶意程序),此时可使用代理模式。
    • 代理可仅在客户端凭据满足要求时将请求传递给服务对象。
  3. 本地执行远程服务(远程代理)。适用于服务对象位于远程服务器上的情形。
    • 在这种情形中,代理通过网络传递客户端请求,负责处理所有与网络相关的复杂细节。
  4. 记录日志请求(日志记录代理)。适用于当你需要保存对于服务对象的请求历史记录时。代理可以在向服务传递请求前进行记录。
  5. 缓存请求结果 (缓存代理)。适用于需要缓存客户请求结果并对缓存生命周期进行管理时,特别是当返回结果的体积非常大时。
    • 代理可对重复请求所需的相同结果进行缓存,还可使用请求参数作为索引缓存的键值。
  6. 智能引用。可以使用某个重量级对象时立即销毁该对象。
    • 代理会将所有获取了指向服务对象或其结果的客户端记录在案。代理会时不时地遍历各个客户端,检查它们是否仍在运行。如果相应的客户端列表为空,代理就会销毁该服务对象,释放底层系统资源。
    • 代理还可以记录客户端是否修改了服务对象。其他客户端还可以复用未修改的对象。

6:代理模式优缺点

优点 缺点
在客户端毫无察觉的情况下控制服务对象。 代码可能会变得复杂,因为需要新建许多类。
如果客户端对服务对象的生命周期没有特殊要求,你可以对生命周期进行管理。 服务响应可能会延迟。
即使服务对象还未准备好或不存在,代理也可以正常工作。
开闭原则。你可以在不对服务或客户端做出修改的情况下创建新代理。

7:代理模式与其他模式关系

  1. 适配器模式能为被封装对象提供不同的接口,代理模式能为对象提供相同的接口,装饰模式则能为对象提供加强的接口。
  2. 外观模式与代理的相似之处在于它们都缓存了一个复杂实体并自行对其进行初始化。代理与其服务对象遵循同一接口,使得自己和服务对象可以互换,在这一点上它与外观不同。
  3. 装饰和代理有着相似的结构,但是其意图却非常不同。这两个模式的构建都基于组合原则,也就是说一个对象应该将部分工作委派给另一个对象。两者之间的不同之处在于代理通常自行管理其服务对象的生命周期, 而装饰的生成则总是由客户端进行控制。

8:代理模式举例

拿另一篇文章中的例子来说:如果想联系一位明星,首先你没法知道他的联系方式,其次,仅联系到明星也是不够,还有很多事情需要他的经纪人处理。而经纪人就是一个代理,通过这个代理,你可以安排明星参加某些活动,也可以在活动之外处理一些其他的事。

代理模式和装饰模式的区别在于:装饰模式是你自行决定穿哪些衣服,而代理模式这些都是由经济人来管理,你只能提出要求而不一定响应。

9:参考