备忘录模式
某些对象的状态在转换的过程中,可能有需要回溯到之前状态的需求。在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Memento {//备忘录,存储原发器对象的内部状态state
public:
Memento(const string& str) :state(str) {}
string getState() const { return state; }
void setState(const string& s) { state = s; }
private:
string state;
};
class Originator {//原发器:创建一个备忘录,记录内部状态(恢复状态)
private:
string state;
public:
void setState(const string& s) {
cout << "Set State to " << s << "." << endl;
state = s;
}
string getState() const {
return state;
}
Memento* createMemento() {
return new Memento(state);
}
void setMemento(Memento* const m) {
state = m->getState();
}
};
class CareTaker {//管理者:保存备忘录,不能对备忘录的内部内容进行操作
private:
Originator* originator;
vector<Memento*> history;
public:
CareTaker(Originator* const orig):originator(orig){}
~CareTaker() {
for (unsigned int i = 0; i < history.size(); ++i)
delete history.at(i);
history.clear();
delete originator;
}
void Save() {
cout << "Save State." << endl;
history.emplace_back(originator->createMemento());
}
void Load() {//撤销
if (history.empty()) {
cout << "Unable to do Load State" << endl;
return;
}
Memento* m = history.back();//取最近的一个
originator->setMemento(m);
cout << "Load state." << endl;
history.pop_back();
delete m;
}
};
int main()
{
Originator* origin = new Originator();
CareTaker* care = new CareTaker(origin);
origin->setState("fight");
care->Save();
origin->setState("relax");
care->Save();
origin->setState("eat");
care->Save();
origin->setState("start");
care->Load();//返回上一级状态
cout << "Actual State is " << origin->getState() << "." << endl;
care->Load();
cout << "Actual State is " << origin->getState() << "." << endl;
delete origin, care;
return 0;
}
运行结果如下:
要点:
1、备忘录(Memonto)存储原发器对象(Originator)的内部状态,在需要时恢复原发器的状态,CareTaker 则充当管理者的角色将状态保存到外部接口供调用。
2、当前很多语言都支持对象序列化,一般采用这种方式实现备忘录模式。