设计模式之享元模式

定义:
运用共享技术服用大量细粒度的对象,降低程序内存的占用,提高程序性能.

实例:
重要体现在对大量细粒度的对象的复用,如:音乐软件根据收费划分出免费用户和会员用户,免费用户只能听部分的免费音乐,会员则可以听全部音乐并可以下载,虽然两种用户的行为有些区别,但它们所享受的音乐来自于一个音乐库,这样保存一份就可以了,音乐库如果新添了音乐直接放到音乐库即可,然后该音乐库可以服务不同形态的用户,音乐库在这里就相当于享元池或缓存池.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 音乐服务
@interface MusicService ()
// 音乐库
@property (nonatomic, strong) NSArray *musicLibrary;

@end

@implementation MusicService

// 听
- (void)listenToMusic:(NSString *)music
{
// ...
}

// 下载
- (void)downloadMusic:(NSString *)music
{
// ...
}

@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
// 免费的音乐服务
@interface FreeMusicService : NSObject

@property (nonatomic, strong) MusicService *musicServic;

- (void)listenFreeMusic:(NSString *)music;

@end

@implementation FreeMusicService

- (void)listenFreeMusic:(NSString *)music
{
if ([music isEqualToString:music])
{
[self.musicService listenMusic:music];
}
else
{
NSLog(@"快去买会员呀");
}
}

@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
// vip 音乐服务
@interface VipMusicService : NSOjbect

@property (nonatomic, strong) MusicService *musicServer;

- (void)listenMusic:(NSString *)music;

- (void)downloadMusic:(NSString *)music;

@end

@implementation VipMusicService

- (void)listenMusic:(NSString *)music
{
[self.musicService listenMusic:music];
}

- (void)downloadMusic:(NSString *)music
{
[self.musicService downloadMusic:music];
}

@end

1
2
3
4
5
6
7
8
9
10
11
12
// 用户使用
MusicService *musicService = [MusicService new];

FreeMusicService *freeService = [FreeMusicService new];
VipMusicService *vipService = [VipMusicService new];

freeService.musicService = musicService;
vipService.musicService = musicService;

[freeService listenFreeMusic:@"free"];
[freeService listenMusic:@"all"];

优点:

  • 使用享元模式可以减少内存中创建细粒度对象的个数,使得相同的对象能够得以服用,降低消耗,提升性能.
  • 享元模式的外部状态相对独立,可以服务任意了不同场景下的对象

缺点:

  • 使用享元需要分离内部和外部状态,增加逻辑
  • 对象在缓冲池中的服用要注意线程安全的问题

总结:

  • 在细粒度非常繁多的时候,享元模式不失为一种好的优化办法