1、备忘录模式(Memento):
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
Originator(发起人):
负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的那些内部状态。
Memento(备忘录):
负责存储Originator对象内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。
Caretaker(管理者):
负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。保存的细节给封装在了Memento中了,那一天要更改保存细节也不用影响客户端了。
2、Memento模式比较适用于功能比较复杂的,但是需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时。Originator可以根据保存的Memento信息还原到前一状态。
如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。
3、使用备忘录模式可以把复杂对象内部信息对其他的对象屏蔽起来。当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
UML图如下:
4、C++代码实现
- #include <iostream>
- #include <string>
- using namespace std;
- /* 备忘录(Memento)类 */
- class Memento
- {
- private:
- string state;
- public:
- Memento();
- /* 构造函数,将相关的数据导入 */
- Memento(string);
- /* 需要保存的数据属性,可以是多个 */
- string GetState();
- };
- Memento::Memento() {
- }
- Memento::Memento(string state) {
- Memento::state = state;
- }
- string Memento::GetState() {
- return Memento::state;
- }
- /* 发起人:Originator类 */
- class Originator
- {
- public:
- /* 需要保存的状态,实际情况可能有多个 */
- string state;
- /* 创建备忘录,将当前需要保存的信息
- 导入并实例化出一个Memento对象。 */
- Memento CreateMemento();
- /* 恢复备忘录,将Memento导
- 入,并将相关数据恢复。 */
- void SetMemento(Memento &);
- /* 显示状态信息 */
- void Show();
- };
- Memento Originator::CreateMemento() {
- return Memento(state);
- }
- void Originator::SetMemento(Memento & memento) {
- state = memento.GetState();
- }
- void Originator::Show() {
- cout << "State = " << state << endl;
- }
- /* 管理(Caretaker)类 */
- class Caretaker
- {
- private:
- Memento memento;
- public:
- /* 设置备忘录 */
- void SetMemento(Memento memento);
- /* 得到备忘录 */
- Memento GetMemento();
- };
- void Caretaker::SetMemento(Memento memento)
- {
- Caretaker::memento = memento;
- }
- Memento Caretaker::GetMemento()
- {
- return memento;
- }
- int main()
- {
- Originator originator;
- originator.state = "on";
- originator.Show();
- Caretaker caretaker;
- /* 备份Originator的状态 */
- caretaker.SetMemento(originator.CreateMemento());
- originator.state = "off";
- originator.Show();
- /* 恢复Originator备份的状态 */
- originator.SetMemento(caretaker.GetMemento());
- originator.Show();
- return 0;
- }