备忘录模式

理论

 备忘录(Memento)模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

 备忘录模式应用场景:

  1. 比较适用于功能比较复杂,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分,Originator 可以根据保存的 Memento 信息还原到前一状态。

  2. 当角色的状态改变的时候,有可能这个状态无效,这时候可以使用暂时存储起来的备忘录将状态复原。

实例

模拟游戏场景,一个游戏角色有生命力、攻击力、防御力等数据,在打Boss前后会不一样,我们允许玩家与Boss决斗的结果不理想时可以让游戏恢复到决斗前

UML类图

代码实现

#include <iostream>
using namespace std;

//游戏状态存储箱类
class RoleStateMemento {
public:
	RoleStateMemento(int _vit, int _atk, int _def) :vit(_vit), atk(_atk), def(_def) {}
	int GetVit() { return vit; }
	int GetAtk() { return atk; }
	int GetDef() { return def; }

private:
	int vit;
	int atk;
	int def;
};

//发起人(Originator)类
class Originator {
public:
	//初始化状态
	void SetState() {
		vit = 100;
		atk = 100;
		def = 100;
	}

	//战斗后状态
	void Battle() {
		vit = 0;
		atk = 0;
		def = 0;
	}

	//保存当前状态到备忘录
	RoleStateMemento* SaveState() { return new RoleStateMemento(vit, atk, def); }

	//恢复备忘录
	void RecoveryState(RoleStateMemento* memento){
		this->vit = memento->GetVit();
		this->atk = memento->GetAtk();
		this->def = memento->GetDef();
	}

	//显示当前状态
	void Display() {
		cout << "当前状态: " << endl;
		cout << "生命力: " << vit << " ";
		cout << "攻击力: " << atk << " ";
		cout << "防御力: " << def << " ";
		cout << endl;
	}

private:
	int vit;  //生命力
	int atk;  //攻击力
	int def;  //防御力
};

//角色状态管理类
class RoleStateCaretaker {
public:
	void SetMemento(RoleStateMemento* memento) { Memento = memento; }
	RoleStateMemento* GetMemento() { return Memento; }

private:
	RoleStateMemento* Memento;
};

//客户端代码
int main()
{
	//战斗前
	Originator role;
	role.SetState();
	role.Display();

	//保存当前进度
	RoleStateCaretaker CreateMemento;
	CreateMemento.SetMemento(role.SaveState());

	//战斗后
	role.Battle();
	role.Display();

	//恢复备忘录
	role.RecoveryState(CreateMemento.GetMemento());
	role.Display();

	system("pause");
	return 0;
}

运行结果

好处:把要保存的细节给封装在了 Memento 中了,如果要更改保存的细节不会影响客户端。

posted @ 2022-09-17 09:52  KYZH  阅读(33)  评论(0编辑  收藏  举报