这个国庆,回家不想学习,于是下了个三国志11,玩了好几天,终于从一个只有一个城池,5、6个武将,一两万士兵的刘备,发展成占有半壁江山了,灭了曹操,袁绍等,那在玩游戏的时候,我肯定不能连续几十个小时都不退出游戏,或者说不关机,那我每次肯定都需要保存游戏进度才能下次继续玩,那这就用上我这次要说的备忘录模式了,每次讲记录保存在存档里,下次进入游戏又可以接着上一次继续玩了~
定义(源于GoF《设计模式》):
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
如何实现这个将状态信息保存在某处呢?使用原型模式?由于对象通常封装了其部分或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态了。由于原型模式总是返回对象的全部状态信息,同时原型模式使其状态能被其它对象访问,这样就违反了封装的原则,还可能有损应用的可靠性和可扩展性。
一个备忘录是一个对象,它存储另一个对象在某个瞬间的所有状态,而后者称为备忘录的原发器。
当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。原发器用描述当前状态的信息初始化该备忘录。
只有原发器可以向备忘录中存取信息,备忘录对其他的对象是“不可见”的。(通过友元来实现!)
关键点:
1、备份对象的状态;
2、不破坏封装!
UML图:(就如我所玩的游戏一样,一般游戏都有存档的限制,我这里设置了最多只能存档16个,当然每个都可以被覆盖!)
代码示例:
#include<iostream> using namespace std; class Memento //备忘录中的原发器对象的内部状态 { private: friend class Originator; Memento(int a,int b,int c):wujiangNum(a),chengchiNum(b),shibingNum(c){}; int wujiangNum; //武将数目 int chengchiNum; //城池数目 int shibingNum; //士兵数目 }; class Originator //备忘录中的原发器,即需要备份的对象,利用Memento把对象的状态提取出来备份,而对象的函数方法等并不需要备份,只需备份状态 { public: Originator() { this->wujiangNum=100; this->chengchiNum=100; this->shibingNum=100; }; ~Originator(); void LoadState(Memento* memo){ //载入存档 this->wujiangNum=memo->wujiangNum; this->chengchiNum=memo->chengchiNum; this->shibingNum=memo->shibingNum; } Memento* SaveState(){ //存档 return new Memento(wujiangNum,chengchiNum,shibingNum); } void SometimeLater(){ //玩了一会之后,状态变化 this->wujiangNum--; this->chengchiNum--; this->shibingNum--; } void showState(){ //展示状态 cout<<this->wujiangNum<<endl<<this->chengchiNum<<endl<<this->shibingNum<<endl; } private: int wujiangNum; //武将数目 int chengchiNum; //城池数目 int shibingNum; //士兵数目 /* data */ }; class Caretakerr //备忘录模式中的,存档管理,就像游戏中的管理16个存档的对象 { public: ~Caretakerr() { }; void SetStateMemento(Memento* pMemento,int index) { memento[index] = pMemento; } Memento *GetStateMemento(int index) { return memento[index] ; } private: Memento* memento[16]; /* data */ }; int main(int argc, char const *argv[]) { Originator* liubei=new Originator();//创建一个刘备 Caretakerr pCaretaker; pCaretaker.SetStateMemento(liubei->SaveState(),1); //存档到第一栏 liubei->showState(); liubei->SometimeLater(); pCaretaker.SetStateMemento(liubei->SaveState(),2); //一段时间后 存档到第二栏 liubei->showState(); liubei->LoadState(pCaretaker.GetStateMemento(1)); //读取第一栏档 liubei->showState(); liubei->LoadState(pCaretaker.GetStateMemento(2)); //读取第二栏档 liubei->showState(); liubei->SometimeLater(); liubei->SometimeLater(); pCaretaker.SetStateMemento(liubei->SaveState(),1); //一段时间后 存档到第一栏 liubei->LoadState(pCaretaker.GetStateMemento(1)); //读取第一栏档 liubei->showState(); }
原文地址:http://blog.csdn.net/liucimin/article/details/39852647