定义

代理模式(Proxy Pattern) :给某一个对象提供一个代 理,并由代理对象控制对原对象的引用。代理模式的英 文叫做Proxy或Surrogate,它是一种对象结构型模式。

模式结构

代理模式包含如下角色:

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

image.png

代码分析

代理是一种通用的设计模式,在iOS中对代理设计模式支持的很好,有特定的语法来实现代理模式,OC语言可以通过@Protocol实现协议。
代理主要由三部分组成:

  • 协议:用来指定代理双方可以做什么,必须做什么。
  • 代理:根据指定的协议,完成委托方需要实现的功能。
  • 委托:根据指定的协议,指定代理去完成什么功能。

这里用一张图来阐述一下三方之间的关系:
image.png

协议类

  1. #import <Foundation/Foundation.h>
  2. @protocol LoginProtocol <NSObject>
  3. @optional
  4. - (void)userLoginWithUsername:(NSString *)username password:(NSString *)password;
  5. @end

委托类

  1. #import <UIKit/UIKit.h>
  2. #import "LoginProtocol.h"
  3. /**
  4. * 当前类是委托类。用户登录后,让代理对象去实现登录的具体细节,委托类不需要知道其中实现的具体细节。
  5. */
  6. @interface LoginViewController : UIViewController
  7. // 通过属性来设置代理对象
  8. @property (nonatomic, weak) id<LoginProtocol> delegate;
  9. @end
  10. 实现部分:
  11. @implementation LoginViewController
  12. - (void)loginButtonClick:(UIButton *)button {
  13. // 判断代理对象是否实现这个方法,没有实现会导致崩溃
  14. if ([self.delegate respondsToSelector:@selector(userLoginWithUsername:password:)]) {
  15. // 调用代理对象的登录方法,代理对象去实现登录方法
  16. [self.delegate userLoginWithUsername:self.username.text password:self.password.text];
  17. }
  18. }

代理方

  1. // 遵守登录协议
  2. @interface ViewController () <LoginProtocol>
  3. @end
  4. @implementation ViewController
  5. - (void)viewDidLoad {
  6. [super viewDidLoad];
  7. LoginViewController *loginVC = [[LoginViewController alloc] init];
  8. loginVC.delegate = self;
  9. [self.navigationController pushViewController:loginVC animated:YES];
  10. }
  11. /**
  12. * 代理方实现具体登录细节
  13. */
  14. - (void)userLoginWithUsername:(NSString *)username password:(NSString *)password {
  15. NSLog(@"username : %@, password : %@", username, password);
  16. }

适用环境

根据代理模式的使用目的,常见的代理模式有以下几种类型:

  • 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个本地 的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在 另一台主机中,远程代理又叫做大使(Ambassador)。
  • 虚拟(Virtual)代理:如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
  • Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟 到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个 开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
  • 保护(Protect or Access)代理:控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
  • 缓冲(Cache)代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
  • 防火墙(Firewall)代理:保护目标不让恶意用户接近。
  • 同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
  • 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来等。

    优点

  • 代理模式能够协调调用者和被调用者,在一定程度上降低了系 统的耦合度。

  • 远程代理使得客户端可以访问在远程机器上的对象,远程机器 可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
  • 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系 统资源的消耗,对系统进行优化并提高运行速度。
  • 保护代理可以控制对真实对象的使用权限。

    缺点

  • 由于在客户端和真实主题之间增加了代理对象,因此 有些类型的代理模式可能会造成请求的处理速度变慢。

  • 实现代理模式需要额外的工作,有些代理模式的实现 非常复杂。