设计模式:备忘录模式 C++实现


前言

今天复习了备忘录模式,感觉挺简单的,这里给大家分享下。


1. 备忘录模式的理解

备忘录模式,就是将对象中的部分或全部数据抽离出来,在另外一个用作备份的类中存储起来,当需要时再从这个备份类中恢复,封装备份与恢复细节。

备忘录模式的定义与类图(引用《大话设计模式》)如下所示:
在这里插入图片描述


2. 备忘录模式 C++实现

这里以备份游戏进度为例,实现备忘录模式。

备份游戏进度的类图(引用《大话设计模式》)如下:
在这里插入图片描述

上述例子的C++实现如下:

#include <iostream>
#include <memory>

//*****************Memo Pattern*****************
//备忘录类
class GameRoleMemento
{
private:
	int vit;
	int atk;
	int def;

public:
	GameRoleMemento(const int nVit, const int nAtk, const int nDef) : vit(nVit), atk(nAtk), def(nDef) {}

	int GetVit() const
	{
		return vit;
	}

	int GetAtk() const
	{
		return atk;
	}

	int GetDef() const
	{
		return def;
	}
};

//管理备忘录类
class RoleStateCaretaker
{
private:
	std::shared_ptr<GameRoleMemento> smartMemento;

public:
	void SetGameRoleMemento(std::shared_ptr<GameRoleMemento> pMemento)
	{
		smartMemento = pMemento;
	}

	std::shared_ptr<GameRoleMemento> GetGameRoleMemento() const
	{
		return smartMemento;
	}
};

//游戏角色类
class GameRole
{
private:
	int vit;//生命力
	int atk;//攻击力
	int def;//防御力

public:
	GameRole(int nVit, int nAtk, int nDef) : vit(nVit), atk(nAtk), def(nDef) {}

	GameRoleMemento* SaveState()
	{
		return new GameRoleMemento(vit, atk, def);
	}

	void DisplayState()
	{
		std::cout << "当前生命力:" << vit << ", 当前攻击力:" << atk << ", 当前防御力:" << def << std::endl;
	}

	void RecoveryState(const GameRoleMemento& memento)
	{
		vit = memento.GetVit();
		atk = memento.GetAtk();
		def = memento.GetDef();
	}

	void Fight()
	{
		vit = 0;
		atk = 0;
		def = 0;
	}
};


//********************Test********************
int main()
{
	std::cout << "大战Boss前" << std::endl;
	std::shared_ptr<GameRole> lixiaoyao = std::make_shared<GameRole>(100, 100, 100);
	lixiaoyao->DisplayState();

	//保存进度
	std::shared_ptr<RoleStateCaretaker> stateAdmin = std::make_shared<RoleStateCaretaker>();
	stateAdmin->SetGameRoleMemento(std::shared_ptr<GameRoleMemento>(lixiaoyao->SaveState()));

	std::cout << "\n大战后" << std::endl;
	lixiaoyao->Fight();
	lixiaoyao->DisplayState();

	std::cout << "\n恢复到大战前:" << std::endl;
	lixiaoyao->RecoveryState(*(stateAdmin->GetGameRoleMemento()));
	lixiaoyao->DisplayState();

	system("pause");
	return 0;
}

总结

备忘录模式的优点是客户端不需要了解备份与还原的细节,只要调用相应的函数即可。在有历史记录和备份还原状态的类中可以使用该设计模式。

备忘录模式的实现感觉违背了开放-封闭原则,扩展性也不是很好,比如:我要新增一个状态信息:魔力值,我要在游戏角色中添加一个魔力值属性,在构造函数中新增魔力值属性的初始化,修改备份游戏属性的函数,当然要事先在备忘录类中的添加魔力值属性,修改备忘录类的构造函数,…。从这里可以看到,新增一个属性,几乎所有的方法都要修改,这真的很不友好。

个人觉得把游戏中的所有属性从角色中分离出来封装成一个新的类-游戏状态类,游戏角色类以组合关系包含一个游戏状态类,对游戏状态的更新由这个新的类来事先,游戏角色类只要调用相应函数即可;备忘录类也只要备份相应的游戏状态类的对象即可,如果以后需要新增或者修改,只要对游戏状态类更新即可。当然可能也会修改游戏角色类和备忘录类,但是个人认为修改的机会少一些。

或者在游戏状态类的基础上,直接在游戏角色类中定义状态类的两个对象,一个表示当前状态信息,一个表示备份状态信息,这样是不是更简单些呢?

欢迎大家留言,给出你的想法,谢谢大家!

参考

《大话设计模式》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值