MEMENTO(备忘录)
1. 意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可将该对象恢复到原先保存的状态。
2. 动机
有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复
过来,需要实现检查点和取消机制 , 而要实现这些机制,你必须事先将状态信息保存在某处,
这样才能将对象恢复到它们先前的状态。但是对象通常封装了其部分或所有的状态信息 , 使得
其状态不能被其他对象访问,也就不可能在该对象之外保存其状态。而暴露其内部状态又将
违反封装的原则,可能有损应用的可靠性和可扩展性。
3.类图
• Memento(备忘录,如SolverState )
— 备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态。
— 防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,管理者(caretaker)只能看到备忘录的窄接口—它只能将备忘录传递给其他对象。相反 , 原发器能够看到一个宽接口, 允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成本备忘录的那个原发器访问本备忘录的内部状态。
• Originator(原发器,如 ConstraintSolver )
— 原发器创建一个备忘录 ,用以记录当前时刻它的内部状态。
— 使用备忘录恢复内部状态 .。
• Caretaker(负责人,如undo mechanism)
— 负责保存好备忘录。
— 不能对备忘录的内容进行操作或检查。
代码:
#pragma once
#include "stdafx.h"
class Memento
{
public:
Memento(const string & s):state(s){}
string getState() const {
return state;
}
void setState(const string & s)
{
state = s;
}
private:
string state;
};
class Originator
{
public:
Originator() {}
Memento createMemento()
{
Memento m(state);
return m;
}
void setMemento(const Memento &m)
{
state = m.getState();
}
private:
string state;
};
void process()
{
Originator originator;
originator.setMemento(Memento("吉儿法师"));
//储存到备忘录
Memento mem = originator.createMemento();
string str = mem.getState();
cout << str << endl;
//然后对originator 改变状态
originator.setMemento(Memento("皮卡丘不皮"));
Memento mem2 = originator.createMemento();
string str2 = mem2.getState();
cout << str2 << endl;
originator.setMemento(mem);
mem2 = originator.createMemento();
str2 = mem2.getState();
cout << str2 << endl;
}
输出结果:
吉儿法师
皮卡丘不皮
吉儿法师
这就是备忘录模式。
参考:
《设计模式》gof
李忠建《设计模式》视频。