前言
所有通过捷径所获取到的快乐,无论是金钱、性还是名望,最终都会给自己带来痛苦。人其实很难抵制诱惑,只能远离诱惑,所以千万不要高看自己的定力。 -- 罗翔
❝在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。 ❞
就是实际的回退功能,将不同时间段的各状态数据依次存储至列表。当需要回退时,从列表取出各状态值载入即可。该模式又叫快照模式。
「备忘录模式」 有点类似后悔药的功能,软件回档和撤回的功能就是备忘录的体现。
玩游戏时,人物的状态(等级和血量)是随时间和操作改变的,设计存档和回退功能,实现某个时间点人物的状态备份,并能够回退上一个备份的状态。
上述场景,主要需要保存当前人物的血量和等级并存入备忘录即可,功能比较简单。
备忘录类图.png
「编程环境」
「工程结构」
Memento/
├── caretaker.cc
├── caretaker.h
├── main.cc
├── Makefile
├── memento.cc
├── memento.h
├── originator.cc
└── originator.h
「备忘录接口」
class CMemento
{
public:
explicit CMemento(void *pInfo, int size);
~CMemento();
int GetInfo(void *info, int size);
private:
std::string date;
void *mpInfo;
};
mpInfo: 在CMemento构造函数分配一块内存用于存储源数据状态值, mpInfo指向这块内存。
「源数据接口」
typedef struct
{
int level;
float blood;
char date[64];
} SAttrValue;
class COriginator
{
public:
COriginator();
~COriginator();
CMemento* Save();
void Restore(CMemento *pMemento);
void SetAttribute(SAttrValue *pAttr);
void ShowInfo();
private:
SAttrValue mAttrValue;
};
「管理者接口」
class CCaretaker
{
public:
explicit CCaretaker(COriginator *pOri);
~CCaretaker();
void Backup();
void Undo();
private:
COriginator *pmOriginator;
std::vector<CMemento*> mMementoArray;
};
「客户端代码」
int main(int argc, char *argv[])
{
COriginator theOriginator;
CCaretaker theCCaretaker(&theOriginator);
MAIN_LOG("---- Backup 1th attribute ----\n");
SAttrValue attrValue = {10, 100, {0}};
theOriginator.SetAttribute(&attrValue);
theCCaretaker.Backup();
theOriginator.ShowInfo();
MAIN_LOG("------------------------------\n\n");
sleep(3);
MAIN_LOG("---- Backup 2th attribute ----\n");
attrValue.level = 66;
attrValue.blood = 80;
theOriginator.SetAttribute(&attrValue);
theCCaretaker.Backup();
theOriginator.ShowInfo();
MAIN_LOG("------------------------------\n\n");
sleep(5);
MAIN_LOG("----- Current attribute -----\n");
attrValue.level = 88;
attrValue.blood = 60;
theOriginator.SetAttribute(&attrValue);
theOriginator.ShowInfo();
MAIN_LOG("------------------------------\n\n");
sleep(4);
MAIN_LOG("--> Wating roll back to the previous version\n");
sleep(2);
theCCaretaker.Undo();
theOriginator.ShowInfo();
MAIN_LOG("------------------------------\n\n");
MAIN_LOG("--> Wating roll back to the previous version\n");
sleep(2);
theCCaretaker.Undo();
theOriginator.ShowInfo();
MAIN_LOG("------------------------------\n\n");
return 0;
}
客户端业务是备份两次,回退两次。
$ ./exe
---- Backup 1th attribute ----
Level: 10
Blood: 100%
Backup time: 2022-04-30 18:07:26
------------------------------
---- Backup 2th attribute ----
Level: 66
Blood: 80%
Backup time: 2022-04-30 18:07:29
------------------------------
----- Current attribute -----
Level: 88
Blood: 60%
------------------------------
--> Wating roll back to the previous version
Level: 66
Blood: 80%
Backup time: 2022-04-30 18:07:29
------------------------------
--> Wating roll back to the previous version
Level: 10
Blood: 100%
Backup time: 2022-04-30 18:07:26
------------------------------
用心感悟,认真记录,写好每一篇文章,分享每一框干货。
更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入“开源519公众号”聊天界面输入“文章目录” 或者 菜单栏选择“文章目录”查看。公众号后台聊天框输入本文标题,在线查看源码。