设计模式笔记-Memento模式
2016-06-01 17:18
344 查看
备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。备忘的用例很多,比如word编辑,按ctrl+z撤消,如果没备忘,肯定是不能撤消回到之前状态的;打过游戏的人应该也了解,比如DOTA1,技术挺落后,不像DOTA2断线可以重连,比赛的时候为了防止游戏崩溃,时不时的裁判要手动保存游戏。
这里的Memento类保存的是Originator类的一个临时状态,它自己是不可以变化的--本来就是要保存原来状态,又被改变了那不是没意义了?所以这里我把Memento类的所有成员都设为private的,然后把Originator设为友元类,这样它就只能被Originator访问了。这个应该是个关注点,但看网上好多人没有这么弄,成员函数都是public的,可能很多人觉得只要我不去调用它不就行了嘛,违反了迪米特法则?“一个对象应该对其他对象保持最少的了解”,这就是设计的精妙。
还有一点就是:为了在Originator类中创建备忘,设计了备忘类Memento的一个带Originator*类型参数的拷贝构造函数!
这里的Memento类保存的是Originator类的一个临时状态,它自己是不可以变化的--本来就是要保存原来状态,又被改变了那不是没意义了?所以这里我把Memento类的所有成员都设为private的,然后把Originator设为友元类,这样它就只能被Originator访问了。这个应该是个关注点,但看网上好多人没有这么弄,成员函数都是public的,可能很多人觉得只要我不去调用它不就行了嘛,违反了迪米特法则?“一个对象应该对其他对象保持最少的了解”,这就是设计的精妙。
还有一点就是:为了在Originator类中创建备忘,设计了备忘类Memento的一个带Originator*类型参数的拷贝构造函数!
//originator.h #include<string> #include "memento.h" class Memento; class Originator { public: Memento* createMemento(); void restoreMemento(Memento *); void setState(string state) { _state = state; } string getState() { return _state; } private: std::string _state; };
//originator.cpp void Originator::restoreMemento(Memento *m) { _state = m->getState(); } Memento* Originator::createMemento() { return new Memento(this); }
//memento.h #include"originator.h" #include<string> class Originator; class Memento { friend class Originator; private: Memento(Originator*); void setState(std::string state) { _state = state; } std::string getState() { return _state; } private: std::string _state; };
//memento.cpp #include "memento.h" Memento::Memento(Originator *o) { _state = o->getState(); }完全可以不用Caretaker类,此时用户代码需要自己处理备份多状态逻辑(用容器)。 简单的实现如下:
class Caretaker { void Save(Memento *lpMemento) { m_vectMemento.push_back(lpMemento); } Memento* Load(int idx) { //这里随便你怎么实现吧 return m_vectMemento[idx]; } private: vector<Memento*> m_vectMemento; };用户代码:
int main() { Originator originator; originator.setState("old"); Memento * meme = originator.createMemento(); originator.setState("new"); originator.restoreMemento(meme); //使用Caretaker类也可以 Originator originator; Caretaker take; originator.setState("old"); Memento * meme = originator.createMemento(); take.Save(meme); originator.setState("new"); originator.restoreMemento(take.Load(0)); return 0; }
相关文章推荐
- SRAM和DRAM的区别
- 自定义异常信息
- el表达式获取div
- ES6学习笔记(七)--Generator函数与Promise对象
- 20 个常用的 CSS 技巧
- poj 2182
- 数组
- quick cocos2dx脚本加密
- hadoop相关随记
- ES6学习笔记(六)--set,map数据结构和for...of遍历
- [从头学数学] 第232节 定积分
- 从0开始学习 GitHub 系列之「Git 速成」
- hadoop相关随记
- docker 监控浅谈
- 团体程序设计天梯赛-练习集 L3-003 社交集群 并查集 解题报告
- CSS3的nth-child() 和nth-of-type()选择器,表格奇偶行变色
- LA 4327 Parade (DP单调队列)
- appledoc 使用方法
- ES6学习笔记(五)--函数与对象
- LightOJ 1045 Digits of Factorial