备忘录模式
理论
备忘录(Memento)模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
备忘录模式应用场景:
1. 比较适用于功能比较复杂,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分,Originator 可以根据保存的 Memento 信息还原到前一状态。
2. 当角色的状态改变的时候,有可能这个状态无效,这时候可以使用暂时存储起来的备忘录将状态复原。
实例
模拟游戏场景,一个游戏角色有生命力、攻击力、防御力等数据,在打Boss前后会不一样,我们允许玩家与Boss决斗的结果不理想时可以让游戏恢复到决斗前
UML类图
代码实现
#include <iostream> using namespace std; //游戏状态存储箱类 class RoleStateMemento { public: RoleStateMemento(int _vit, int _atk, int _def) :vit(_vit), atk(_atk), def(_def) {} int GetVit() { return vit; } int GetAtk() { return atk; } int GetDef() { return def; } private: int vit; int atk; int def; }; //发起人(Originator)类 class Originator { public: //初始化状态 void SetState() { vit = 100; atk = 100; def = 100; } //战斗后状态 void Battle() { vit = 0; atk = 0; def = 0; } //保存当前状态到备忘录 RoleStateMemento* SaveState() { return new RoleStateMemento(vit, atk, def); } //恢复备忘录 void RecoveryState(RoleStateMemento* memento){ this->vit = memento->GetVit(); this->atk = memento->GetAtk(); this->def = memento->GetDef(); } //显示当前状态 void Display() { cout << "当前状态: " << endl; cout << "生命力: " << vit << " "; cout << "攻击力: " << atk << " "; cout << "防御力: " << def << " "; cout << endl; } private: int vit; //生命力 int atk; //攻击力 int def; //防御力 }; //角色状态管理类 class RoleStateCaretaker { public: void SetMemento(RoleStateMemento* memento) { Memento = memento; } RoleStateMemento* GetMemento() { return Memento; } private: RoleStateMemento* Memento; }; //客户端代码 int main() { //战斗前 Originator role; role.SetState(); role.Display(); //保存当前进度 RoleStateCaretaker CreateMemento; CreateMemento.SetMemento(role.SaveState()); //战斗后 role.Battle(); role.Display(); //恢复备忘录 role.RecoveryState(CreateMemento.GetMemento()); role.Display(); system("pause"); return 0; }
运行结果
好处:把要保存的细节给封装在了 Memento 中了,如果要更改保存的细节不会影响客户端。