备忘录模式
定义:捕获一个对象的内部状态,并在该对象之外保存这个状态。以后就可以将该对象恢复到之前被保存的状态。
UML类图:
以上
Originator是发起者,它负责创建一个备忘录Memento,记录当前时刻它的内部状态,并可使用备忘录Memento恢复内部状态。
Memento是备忘录,负责存储Originator对象的当前状态。
Caretaker是管理者,只负责保存备忘录Memento对象,但是不能对备忘录的内容进行任何操作。
场景模拟:
以前特别喜欢玩s11Pk版,有时候玩了一段时间,发现进展和预想的不一样,上将军邢道荣被敌方抓了,但又不想重新开始,于是重新读档,回到之前的状态,继续玩。
栗子代码:
其中
类图Originator对应San11PkPlayer.
Memento对应San11PkStorage.
Caretaker对应ManageSan11PkStorage.
#include <iostream>
#include <vector>
using namespace std;
class San11PkStorage;
//备忘录角色
class San11PkStorage{
public:
San11PkStorage(std::string weather,vector<std::string> mapRoles)
{
this->m_weather = weather;
this->m_inMaproles = mapRoles;
}
//private: //为了方便,这里直接用public
public:
std::string m_weather; //天气
vector<std::string> m_inMaproles; //在地图上的角色
//...
};
//备忘录管理员角色
class ManageSan11PkStorage{
public:
void setS11(San11PkStorage *s11)
{
m_s11 = s11;
}
San11PkStorage* getS11()
{
return m_s11;
}
private:
San11PkStorage *m_s11;
};
//发起人角色
class San11PkPlayer
{
public:
//保存
San11PkStorage* saveS11Status()
{
return new San11PkStorage(m_weather, m_inMaproles);
}
//恢复
void recoveryS11Status(const San11PkStorage &s11s)
{
this->m_weather = s11s.m_weather;
this->m_inMaproles = s11s.m_inMaproles;
}
//展示数据
void showS11()
{
cout << "现在的季节是:" << m_weather.c_str() << endl;
auto iter = m_inMaproles.begin();
for (; iter != m_inMaproles.end(); iter++)
{
cout << "当前地图上的角色有:" << (*iter).c_str() << endl;
}
}
//private:
public:
std::string m_weather; //天气
vector<std::string> m_inMaproles; //在地图上的角色
};
//客户端
int main()
{
San11PkPlayer* pS11 = new San11PkPlayer;
//现在的状态
cout << "================开始玩游戏...===============" << endl;
pS11->m_weather = "冬天";
vector<std::string> vec;
vec.push_back("张辽");
vec.push_back("貂蝉");
vec.push_back("邢道荣");
pS11->m_inMaproles = vec;
pS11->showS11();
//保存当前状态
ManageSan11PkStorage *manager = new ManageSan11PkStorage;
manager->setS11(pS11->saveS11Status());
cout << "================玩了一段时间,不想玩了,读档再来===============" << endl;
vec.at(0) = "张飞";
vec.pop_back();
pS11->m_inMaproles = vec;
pS11->m_weather = "春天";
pS11->showS11();
cout << "================读档后===============" << endl;
pS11->recoveryS11Status(*manager->getS11());
pS11->showS11();
if (manager)
{
delete manager;
manager = nullptr;
}
if (pS11)
{
delete pS11;
pS11 = nullptr;
}
return 0;
}
效果: