设计模式之备忘录

定义:
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。

实例:
备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,当前很多软件都提供了撤销操作,其中就使用了备忘录模式。

角色状态

1
2
3
4
5
6
7
8
9
10
11
@interface PlayerState : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSUInteger level;
@property (nonatomic, assign) NSUInteger rank;

@end

@implementation PlayerState

@end

角色类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@interface Player : NSObject

@property (nonatomic, strong) PlayerState *state; // 角色状态

// 设置角色状态
- (void)setPlayerName:(NSString *)name level:(NSUInteger)level rank:(NSUInteger)rank;

@end

@implementation Player
- (void)setPlayerName:(NSString *)name level:(NSUInteger)level rank:(NSUInteger)rank {
if (!_state) _state = [PlayerState new];
_state.name = name;
_state.level = level;
_state.rank = rank;
}
@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
@interface Memorandum : NSObject

// 存储
- (void)storeWithPlayer:(Player *)player;
// 恢复
- (void)restoreWithPlayer:(Player *)player;

@end


@interface Memorandum ()

@property (nonatomic, strong) PlayerState *state; // 备忘录存储的角色状态

@end

@implementation Memorandum

- (void)storeWithPlayer:(Player *)player {
_state = player.state;
}

- (void)restoreWithPlayer:(Player *)player {
if(_state) player.state = _state;
}

@end

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
// 创建角色 A
Player *playA = [Player new];
[playA setPlayerName:@"King" level:99 rank:30];

// 创建备忘录并保存角色 A 的状态
Memorandum *memorandum = [Memorandum new];
[memorandum storeWithPlayer:playA];

// 创建角色 B 并使用备忘录恢复状态
Player *playB = [Player new];
[memorandum restoreWithPlayer:playB];
NSLog(@"name:%@ level:%ld rank:%ld", playB.state.name, playB.state.level, playB.state.rank);

优点:

  • 它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
  • 备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

缺点:

  • 资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。