备忘录模式(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;
}