设计模式之代理

定义:
代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问.

实例:
通过代理对象解决直接访问目标对象给系统带来的不必要复杂性.如:在Windows上打开一个程序,有快捷方式的时候直接点击快捷方式便可以打开,如果没有快捷方式,则需要问下小李程序安装在那个盘下了?啊,D盘呀,那个目录下了? xxx目录呀, 麻蛋, 咋有俩, … ,在这个片段中快捷方式便是代理,提供了一个控制对这个程序的访问.

1
2
3
4
5
6
// 协议
@protocal Image <NSObject>

- (void)displayImage;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 假装是比较复杂的系统
@interface RealImage : NSObject <Image>

- (instancetype)initWithFileName:(NSString *)fileName;

@end

@implementation RealImage
{
NSString *_fileName;
}

- (instancetype)initWithFileName:(NSString *)fileName
{
self = [super init];
if (self)
{
_fileName = fileName;
[self loadImageFromDisk];
}
return self;
}

- (void)loadImageFromDisk
{
NSLog(@"Loading %@", _fileName);
}

/** Image协议方法 */
- (void)displayImage
{
NSLog(@"Displaying %@",_fileName);
}

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 代理类
@interface ProxyImage :NSObject <Image>

- (instancetype)initWithFileName:(NSString *)fileName;

@end

@implementation ProxyImage
{
NSString *_fileName;
RealImage *_image;
}

- (instancetype)initWithFileName:(NSString *)fileName
{
if (self = [super init])
{
_fileName = fileName;
}
return self;
}

- (void)displayImage
{
if(_image == nil)
{
_image = [[RealImage alloc] initWithFileName:_fileName];
}
[_image displayImage];
}
@end
1
2
3
4
5
6
// 使用
ProxyImage *pImage = [[ProxyImage alloc] initWithFileName:@"moe_photo1"];
[pImage displayImage];

ProxyImage *pImage2 = [[ProxyImage alloc] initWithFileName:@"moe_photo2"];
[pImage22 displayImage];

优点:

  • 降低了用户与系统的耦合度: 代理对象能协调调用者和被调用者
  • 通过代理可以对用户访问系统的过程做不同的控制
  • 在某些场景下可以减少字眼的小号
  • 可以通过代理控制用户对系统操作的权限

缺点:

  • 在用户和系统之间增加了一层代理层,有可能引起用户的请求相应速度变慢

总结:

  • 结合业务场景选用是否增加代理层