-
备忘录模式:一种行为型设计模式
-
应用场景:
备忘录模式是对原型模式的进一步思考,因为有些时候我们并不需要一个完整对象的拷贝,只需要拷贝对象的一部分数据作为备份即可。
最典型的例子是虚拟机VWware,它的快照功能用以保存系统当前状态以便日后恢复。但如果是使用原型模式实现这个功能,每次快照时都需要生成一个完整的系统文件,是非常占用空间的。于是便进一步思考, 备份的时候只备份系统中必要的状态信息,日后通过这份不完整的备份信息,也可以使系统恢复到快照中的状态,就可以避免无用的备份信息占用空间。
每次的快照就是备忘记录,再指定一个管理者来管理所有的快照,这就是备忘录模式。 -
举例:
假设有一个游戏角色,它有很多属性,如姓名、血量、攻击力等,在存档备份的时候并不需要生成一个完整的角色对象作为拷贝,只需要存储血量、攻击力即可,因为姓名不会随着游戏进度更改。 -
实现方式:
为角色类创建一个对应的备份类,该类中只将必要的备份信息作为成员变量
在角色类中实现一个方法,该方法创建一个备份类对象作为返回值。
然后再创建一个管理者类,使用容器存放备份类对象。
以下是备忘录模式的简单代码实现
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//单条备忘的记录
class Memento
{
public:
Memento(uint32_t uiLevel, uint32_t uiHp, uint32_t uiAttack)
:m_uiLevel(uiLevel),m_uiHp(uiHp),m_uiAttack(uiAttack)
{
}
public:
uint32_t m_uiLevel;
uint32_t m_uiHp;
uint32_t m_uiAttack;
};
//需要保存的数据类
class GameRole
{
public:
GameRole(string strName)
:m_strName(strName)
,m_uiLevel(1)
,m_uiHp(100)
,m_uiAttack(10)
{
}
void Show()
{
cout << "Name:" << m_strName << " Level:" << m_uiLevel << " HP:" << m_uiHp << " ATK:" << m_uiAttack << endl;
}
Memento* Save()
{
Memento* pSaveInfo = new Memento(m_uiLevel, m_uiHp, m_uiAttack);
return pSaveInfo;
}
void Load(Memento* pMem)
{
m_uiLevel = pMem->m_uiLevel;
m_uiHp = pMem->m_uiHp;
m_uiAttack = pMem->m_uiAttack;
cout << "Loaded" << endl;
}
private:
string m_strName;
public:
uint32_t m_uiLevel;
uint32_t m_uiHp;
uint32_t m_uiAttack;
};
//备忘管理者
class Recorder
{
public:
void Record(Memento* pMem)
{
vecMemento.push_back(pMem);
cout << "Saved" << endl;
}
Memento* Get(uint32_t uiIndex)
{
return vecMemento[uiIndex];
}
private:
vector<Memento*> vecMemento;
};
主函数中的使用
int main()
{
Recorder oRecorder;
GameRole oPlayer("Mark");
oPlayer.Show();
oRecorder.Record(oPlayer.Save());
oPlayer.m_uiLevel = 100;
oPlayer.m_uiHp = 1000;
oPlayer.m_uiAttack = 100;
oPlayer.Show();
oPlayer.Load(oRecorder.Get(0));
oPlayer.Show();
return 0;
}
控制台输出结果
Name:Mark Level:1 HP:100 ATK:10
Saved
Name:Mark Level:100 HP:1000 ATK:100
Loaded
Name:Mark Level:1 HP:100 ATK:10
如有错误,欢迎指正
网友评论