引入表示实例状态的角色,在保存和恢复实例时有效地防止对象的封装性遭到破坏。
示例
一个收集水果和获取金钱数的掷骰子游戏,游戏规则很简单,具体如下。
- 游戏是自动进行的
- 游戏的主人公通过掷骰子来决定下一个状态
- 当骰子点数为1的时候,主人公的金钱会增加
- 当骰子点数为2的时候,主人公的金钱会减少
- 当骰子点数为6的时候,主人公会得到水果
- 主人公没有钱时游戏就会结束
类图
时序图
Memento类
1 | package game; |
Gamer类
1 | package game; |
Main类
1 | import game.Gamer; |
运行结果
1 | ==== 0 |
登场角色
Originator(生成者)
Originator角色会在保存自己的最新状态时生成Memento角色。当把以前保存的Memento角色传递给Originator角色时,它会将自己恢复至生成该Memento角色时的状态。在示例程序中,由Gamer类扮演此角色。
Memento(纪念品)
Memento角色会将Originator角色的内部信息整合在一起。在Memento角色中虽然保存了Originator角色的信息,但它不会向外部公开这些信息。
Memento角色有以下两种接口(API)。
- wide interface——宽接口(API)
Memento角色提供的“宽接口(API)”是指所有用于获取恢复对象状态信息的方法的集合。由于宽接口(API)会暴露所有Memento角色的内部信息,因此能够使用宽接口(API)的只有Originator角色。
- narrow interface——窄接口(API)
Memento角色为外部的Caretaker角色提供了“窄接口(API)”。可以通过窄接口(API)获取的Memento角色的内部信息非常有限,因此可以有效地防止信息泄露。
通过对外提供以上两种接口(API),可以有效地防止对象的封装性被破坏。
在示例程序中,由Memento类扮演此角色。
Originator角色和Memento角色之间有着非常紧密的联系。
Caretaker(负责人)
当Caretaker角色想要保存当前的Originator角色的状态时,会通知Originator角色。Originator角色在接收到通知后会生成Memento角色的实例并将其返回给Caretaker角色。由于以后可能会用Memento实例来将Originator恢复至原来的状态,因此Caretaker角色会一直保存Memento实例。在示例程序中,由Main类扮演此角色。
不过,Caretaker角色只能使用Memento角色两种接口(API)中的窄接口(API),也就是说它无法访问Memento角色内部的所有信息。它只是将Originator角色生成的Memento角色当作一个黑盒子保存起来。
虽然Originator角色和Memento角色之间是强关联关系,但Caretaker角色和Memento角色之间是弱关联关系。Memento角色对Caretaker角色隐藏了自身的内部信息。