备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样,以后就可以将该对象恢复到原先保存的状态。备忘录模式UML图如下:
下面是一个用C++描述的备忘录模式的基本框架。
#include <iostream>
#include <string>
using namespace std;
// 备忘录
class Memento {
public:
// 保存数据
Memento(const string &str = "")
{
state = str;
}
// 提取数据
const string& State() const
{
return state;
}
private:
string state;
};
// 保存备忘录的管理者
class Caretaker {
public:
// 得到备忘录
void SetMemento(Memento *mem)
{
Memento = mem;
}
// 取出备忘录
Memento* GetMemento()
{
return Memento;
}
~Caretaker()
{
delete Memento; // 销毁备忘录
}
private:
Memento *Memento; // 保存一个备忘录
};
class Originator {
public:
// 设置状态
void SetState(const string &str)
{
state = str;
}
// 获得当前状态
const string& GetState()
{
return state;
}
// 创建备忘录
Memento* CreateMemento()
{
return new Memento(state);
}
// 从备忘录恢复
void SetMemento(const Memento *Memento)
{
state = Memento->State();
}
private:
string state; // 发起人的状态
};
int main()
{
Originator origin;
// 设置状态并打印
origin.SetState("Hello world!");
cout << origin.GetState() << endl;
// 创建备忘录并保存到Caretaker中
Caretaker care;
care.SetMemento(origin.CreateMemento());
// 更改状态并打印
origin.SetState("nihao!");
cout << origin.GetState() << endl;
// 恢复更改之前的状态并打印
origin.SetMemento(care.GetMemento());
cout << origin.GetState() << endl;
system("pause");
return 0;
}
运行结果:
我们将需要保存的状态放在了Memento类中,而Memento类又是由Caretaker来管理的。使用备忘录可以把复杂的对象内部信息对其它对象屏蔽起来。当Originator需要恢复到先前的状态时,就直接从备忘录中提取状态,避免了客户代码中一条条的赋值语句。但备忘录模式也有自己的缺点:如果Originator类中的状态信息很多,那么备忘录将占用大量空间。
参考:
《大话设计模式》第18章