备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
备忘录模式:
逻辑分析:
定义一个中间类,保存使用类对象的中间状态,有利于下次的恢复。
参考网址:C++设计模式——备忘录模式_CoderAldrich的专栏-CSDN博客_c++备忘录模式
为了状态的安全,使用c++的友元类特性,只有特定的类才可以进行数据的读取。
使用场景:
如编辑文档时,撤销功能;
如命令模式中,撤销命令的逻辑功能
如游戏场景中,游戏角色的相关状态的保存。
源码demo:
/********************************************************** 备忘录模式: 就是用一个类来保存一个类的中间状态;;;;; 如果想大规模的保存和管理状态那么就要是用一个管理类------- -------就好比命令模式的时候,命令太多的话,我们在把他给管理起来------------ 发起类中要有: 设置状态的成员函数,创建包含当前状态信息的对象 通过管理类中的,发起类的指针传递,设置当前类中的状态。 *********************************************************/ #include <iostream> #include <string> using namespace std; class Memo; class Originator//初始状态类,我们想保存其中一个状态 { public: string state; Memo* CreateMemo(); void SetMemo(Memo* memo); void Show(){ cout << "状态:" << state << endl; } }; class Memo//备忘录类,保存状态所使用到的结构 { public: string state; Memo(string strState){ state = strState; } }; Memo* Originator::CreateMemo(){ return new Memo(state); }//通过返回一个包含中间状态的对象 void Originator::SetMemo(Memo* memo){ state = memo->state; } class Caretaker//管理者类 { public: Memo* memo;//管理者类中包含了,保存状态的结点对象的指针 }; //这样就可以通过这个指针,操作结点的状态 int main() { Originator* on = new Originator(); on->state = "on"; on->Show(); Caretaker* c = new Caretaker();//使用此指针指向这个,包含中间状态的对象 c->memo = on->CreateMemo();//保存了这个状态,可以恢复 on->state = "off"; on->Show(); on->SetMemo(c->memo); //恢复 on->Show(); // system("pause"); return 0; }
参考:C++设计模式——备忘录模式_CoderAldrich的专栏-CSDN博客_c++备忘录模式,样例感觉蛮好的,尤其是友元类的使用技巧
#include <iostream> using namespace std; //备忘录的类 保存一些必要的中间状态 如游戏人物的临时状态 class RoleStateMemento { public: RoleStateMemento(unsigned iBlood, unsigned iAttack, unsigned iDefense) : m_iBlood(iBlood), m_iAttack(iAttack), m_iDefense(iDefense){} private: friend class GameRole; //定义友元类 可以被这个业务类访问 把相关状态保存下来 unsigned GetBloodValue() { return m_iBlood; } unsigned GetAttackValue() { return m_iAttack; } unsigned GetDefenseValue() { return m_iDefense; } unsigned m_iBlood; // 生命力 unsigned m_iAttack; // 攻击力 unsigned m_iDefense; // 防御力 }; //业务执行类 class GameRole { public: GameRole() : m_iBlood(100), m_iAttack(100), m_iDefense(100){} // 存档 RoleStateMemento *SaveState() { return new RoleStateMemento(m_iBlood, m_iAttack, m_iDefense); } // 恢复存档 void RecoveryState(RoleStateMemento *pRoleState) { m_iBlood = pRoleState->GetBloodValue(); m_iAttack = pRoleState->GetAttackValue(); m_iDefense = pRoleState->GetDefenseValue(); cout<<"Recovery..."<<endl; } void ShowState() { cout<<"Blood:"<<m_iBlood<<endl; cout<<"Attack:"<<m_iAttack<<endl; cout<<"Defense:"<<m_iDefense<<endl; } void Fight() { m_iBlood -= 100; m_iAttack -= 10; m_iDefense -= 20; if (m_iBlood == 0) { cout<<"Game Over"<<endl; } } private: unsigned m_iBlood; // 生命力 unsigned m_iAttack; // 攻击力 unsigned m_iDefense; // 防御力 }; class RoleStateCaretaker { public: void SetRoleStateMemento(RoleStateMemento *pRoleStateMemento) { m_pRoleStateMemento = pRoleStateMemento; } RoleStateMemento *GetRoleStateMemento() { return m_pRoleStateMemento; } private: RoleStateMemento *m_pRoleStateMemento; }; int main() { GameRole *pLiXY = new GameRole(); // 创建李逍遥这个角色 pLiXY->ShowState(); // 显示初始的状态 // 存档 RoleStateCaretaker *pRoleStateCaretaker = new RoleStateCaretaker(); pRoleStateCaretaker->SetRoleStateMemento(pLiXY->SaveState()); //保存了状态 // 开始打大BOSS pLiXY->Fight(); pLiXY->ShowState(); // 读档,从新开始 pLiXY->RecoveryState(pRoleStateCaretaker->GetRoleStateMemento());//恢复状态 pLiXY->ShowState(); if(pLiXY != nullptr) { delete pLiXY; pLiXY = nullptr; } if(pRoleStateCaretaker != nullptr) { delete pRoleStateCaretaker; pRoleStateCaretaker = nullptr; } return 0; }