第十八章 如果再回到从前-备忘录模式(读书笔记)

第十八章 如果再回到从前-备忘录模式

18.1 如果再给我一次机会
 玩单机游戏的时候,我们都是在打大BOSS之前先保存一个进度,然后如果通关失败了,可以再返回刚才那个进度来从头来过。这里就会引入备忘录模式。

18.2 游戏存进度
 游戏角色类,用来存储角色的生命力,攻击力,防御力的数据。但是在这个程序中,代码没有错但未必优。

GameRole.h

#pragma once
#include <iostream>

class GameRole
{
public:
	int GetVitality(void)
	{
		return m_vit;
	};
	void SetVitality(int vit)
	{
		m_vit = vit;
	};
	int GetAttack(void)
	{
		return m_atk;
	};
	void SetAttack(int atk)
	{
		m_atk = atk;
	};

	int GetDefense(void)
	{
		return m_def;
	};
	void SetDefense(int def)
	{
		m_def = def;
	};

	void StateDisplay(void)
	{
		std::cout << "栶偺忬懺:\n"
			<< "懱椡:" << m_vit << "\n"
			<< "峌寕椡:" << m_atk << "\n"
			<< "杊屼椡:" << m_def << std::endl;
	};
	
	void GetInitState(void)
	{
		m_vit = 100;
		m_atk = 100;
		m_def = 100;
	};
	
	void Fight(void)
	{
		m_vit = 0;
		m_atk = 0;
		m_def = 0;
	};
private:
	int m_vit;
	int m_atk;
	int m_def;
};
#include "GameRole.h"

int _tmain(int argc, _TCHAR* argv[])
{
	GameRole* lixiaoyao = new GameRole();
	lixiaoyao->GetInitState();
	lixiaoyao->StateDisplay();

	GameRole* backup = new GameRole();
	backup->SetAttack(lixiaoyao->GetAttack());
	backup->SetDefense(lixiaoyao->GetDefense());
	backup->SetVitality(lixiaoyao->GetVitality());

	lixiaoyao->Fight();
	lixiaoyao->StateDisplay();

	lixiaoyao->SetAttack(backup->GetAttack());
	lixiaoyao->SetDefense(backup->GetDefense());
	lixiaoyao->SetVitality(backup->GetVitality());

	lixiaoyao->StateDisplay();

	delete lixiaoyao;
	delete backup;
	return 0;
}

 

在这块代码中,暴露了实现的细节,所以不足取。

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

 

Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻他的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定Memento存储Originator的那些内部状态。

Memento(备忘录):负责存储Originator对象的内部状态,并可防止Originator以外的其它对象访问备忘录Memento。

Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

18.4 备忘录模式基本代码

Caretaker.h

#pragma once
#include "Memento.h"

class Caretaker
{
public:
	void SetMemento(Memento* p)
	{
		m_pMemento = p;
	};
	Memento* GetMemento(void)
	{
		return m_pMemento;
	};
	~Caretaker()
	{
		delete m_pMemento;
	};
private:
	Memento* m_pMemento;
};


Memento.h

#pragma once
#include <iostream>
#include <string>


class Memento
{
public:
	Memento(std::string state)
	{
		m_State = state;
	};

	std::string GetState(void)
	{
		return m_State;
	};
private:
	std::string m_State;
};

Originator.h

#pragma once
#include "Memento.h"

class Originator
{
public:
	void SetState(std::string state)
	{
		m_State = state;
	};
	std::string GetState(void)
	{
		return m_State;
	};

	Memento* CreateMemento()
	{
		return new Memento(m_State);
	};

	void SetMemento(Memento* p)
	{
		m_State = p->GetState();
	};

	void Show()
	{
		std	::cout << "State=" << m_State << std::endl;
	};
private:
	std::string m_State;
};

 客户端程序

#include "stdafx.h"
#include "Caretaker.h"
#include "Originator.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Originator* o = new Originator();
	o->SetState("On");
	o->Show();

	Caretaker* c = new Caretaker();
	c->SetMemento(o->CreateMemento());

	o->SetState("OFF");
	o->Show();

	o->SetMemento(c->GetMemento());
	o->Show();
	return 0;
}

把要保存的细节给封装在了Memento中了,哪一天要更改保存的细节也不用影响客户端了。备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。
如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。有时一些对象的内部信息必须保存在对象以外的地方,但是必须要由对象自己读取,这时候使用备忘录可以把复杂的对象内部信息对其它的对象屏蔽起来,从而可以恰当地保持封装的边界。
当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

18.5 游戏进度备忘

 

游戏角色类

#pragma once
#include "RoleStateMemento.h"
#include <iostream>

class GameRole
{
public:
	RoleStateMemento* SaveState(void)
	{
		return new RoleStateMemento(m_vit, m_atk, m_def);
	};

	void RecoveryState(RoleStateMemento* p)
	{
		m_vit = p->GetVitality();
		m_atk = p->GetAttack();
		m_def = p->GetDefense();
	};
	void StateDisplay(void)
	{
		std::cout << "栶偺忬懺:\n"
			<< "懱椡:" << m_vit << "\n"
			<< "峌寕椡:" << m_atk << "\n"
			<< "杊屼椡:" << m_def << std::endl;
	};
	void GetInitState(void)
	{
		m_vit = 100;
		m_atk = 100;
		m_def = 100;
	};
	void Fight(void)
	{
		m_vit = 0;
		m_atk = 0;
		m_def = 0;
	};
private:
	int m_vit;
	int m_atk;
	int m_def;
};

角色状态管理者类

#pragma once
#include "RoleStateMemento.h"

class RoleStateCaretaker
{
public:
	RoleStateMemento* GetRoleStateMemento()
	{
		return m_pRoleStateMemento;
	};
	void SetRoleStateMemento(RoleStateMemento* p)
	{
		m_pRoleStateMemento = p;
	};

	RoleStateCaretaker()
		:m_pRoleStateMemento(NULL)
	{
	};

	~RoleStateCaretaker()
	{
		delete m_pRoleStateMemento;
		m_pRoleStateMemento = NULL;
	};

private:
	RoleStateMemento* m_pRoleStateMemento;
};


角色状态存储箱类

#pragma once

class RoleStateMemento
{
public:
	RoleStateMemento(int vit, int atk, int def)
	{
		m_vit = vit;
		m_atk = atk;
		m_def = def;		
	};
	int GetVitality(void)
	{
		return m_vit;
	};
	void SetVitality(int vit)
	{
		m_vit = vit;
	};
	int GetAttack(void)
	{
		return m_atk;
	};
	void SetAttack(int atk)
	{
		m_atk = atk;
	};
	int GetDefense(void)
	{
		return m_def;
	};
	void SetDefense(int def)
	{
		m_def = def;
	};
private:
	int m_vit;
	int m_atk;
	int m_def;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的横打

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值