1. 情景与意图
在我们平时打游戏的时候,为了避免任务完成失败重头的悲剧,我们通常会存档,失败后或者退出游戏后,下次进来我们会读档。这就是一个备忘的功能。
在日常的开发中,我们有时候需要距离对象的某些状态,在对象执行完一些行为后,返回这些状态。应该怎样来设计这样的开发呢?备忘录模式
2. 备忘录模式
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
概念不好理解,我们直接上代码。
3. 备忘录
首先对象要保存的状态可能不止一种,但是为了代码简洁,这里我们只使用一个状态作为演示。
class DPMemento {
// 注意
// 状态可能不止一种,这里只是作为演示
std::string _state;
public:
DPMemento(const std::string& state);
std::string getState();
};
定义需要备忘的对象类
class DPOriginator {
// 这里的状态和备忘录的状态对应,这里有多少需要备忘的状态,备忘录对象就创建多少状态属性
std::string _state;
public:
DPOriginator(const std::string& state);
void change(std::string state);
void getState();
DPMemento saveStateToMemento();
void restoreFromMemento(DPMemento& mem);
};
这里呢,我们其实还可以定义个一个DPCareTaker
的类,用来管理备忘录对象。比如
class DPMemento;
class DPCareTaker {
private:
unordered_map<std::strubg, Memento> _mementoMap;
public:
// 可以使用引用
void addMemento(Memento memento, std::string key){
if (key.size() > 0) _mementoMap[key] = memento;
}
Memento get(std::string key){
return _mementoMap[key];
}
}
现在来看看具体的表现。
int main() {
DPOriginator origin(std::string("bind"));
origin.getState();
origin.change(std::string("recv"));
origin.getState();
DPMemento mem = origin.saveStateToMemento();
origin.change(std::string("send"));
origin.getState();
// 这里没有用到DPCareTaker类。。。
origin.restoreFromMemento(mem);
origin.getState();
return 0;
}
4. 大总结
备忘录模式和前面的状态模式都属于“状态变化”类型的模式。我们知道在组件构建的过程中,总会有面临对象的各种状态的变更,如果有效的管理这些变化,从而让局部系统甚至整个系统趋于稳定。“状态变化”类型的设计模式提供了解决方案。
C++实现备忘录模式源码:【备忘录模式C++源码】