首页 > 代码库 > 设计模式之:备忘录模式

设计模式之:备忘录模式

前言:

   这个国庆,回家不想学习,于是下了个三国志11,玩了好几天,终于从一个只有一个城池,5、6个武将,一两万士兵的刘备,发展成占有半壁江山了,灭了曹操,袁绍等,那在玩游戏的时候,我肯定不能连续几十个小时都不退出游戏,或者说不关机,那我每次肯定都需要保存游戏进度才能下次继续玩,那这就用上我这次要说的备忘录模式了,每次讲记录保存在存档里,下次进入游戏又可以接着上一次继续玩了~




定义(源于GoF《设计模式》)

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

 如何实现这个将状态信息保存在某处呢?使用原型模式?由于对象通常封装了其部分或所有的状态信息,使得其状态不能被其他对象访问,也就不可能在该对象之外保存其状态了。由于原型模式总是返回对象的全部状态信息,同时原型模式使其状态能被其它对象访问,这样就违反了封装的原则,还可能有损应用的可靠性和可扩展性。
 
 一个备忘录是一个对象,它存储另一个对象在某个瞬间的所有状态,而后者称为备忘录的原发器。
 当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。原发器用描述当前状态的信息初始化该备忘录。
 只有原发器可以向备忘录中存取信息,备忘录对其他的对象是“不可见”的。(通过友元来实现!)


关键点:

1、备份对象的状态;

2、不破坏封装!


UML图:(就如我所玩的游戏一样,一般游戏都有存档的限制,我这里设置了最多只能存档16个,当然每个都可以被覆盖!)


代码示例:

#include<iostream>
using namespace std;

class Memento              //备忘录中的原发器对象的内部状态
{

private:
	 friend class Originator;
	 Memento(int a,int b,int c):wujiangNum(a),chengchiNum(b),shibingNum(c){};
	int wujiangNum;     //武将数目
	int chengchiNum;	//城池数目
	int shibingNum;		//士兵数目

};

class Originator     //备忘录中的原发器,即需要备份的对象,利用Memento把对象的状态提取出来备份,而对象的函数方法等并不需要备份,只需备份状态
{
public:
	Originator()
	{

		this->wujiangNum=100;
		this->chengchiNum=100;
		this->shibingNum=100;


	};
	~Originator();
	void LoadState(Memento* memo){               //载入存档

		this->wujiangNum=memo->wujiangNum;
		this->chengchiNum=memo->chengchiNum;
		this->shibingNum=memo->shibingNum;


	}
	Memento* SaveState(){					//存档

		return new Memento(wujiangNum,chengchiNum,shibingNum);


	}

	void SometimeLater(){					//玩了一会之后,状态变化

		this->wujiangNum--;
		this->chengchiNum--;
		this->shibingNum--;


	}

	void showState(){					//展示状态

		cout<<this->wujiangNum<<endl<<this->chengchiNum<<endl<<this->shibingNum<<endl;

	}
private:
		int wujiangNum;     //武将数目
		int chengchiNum;	//城池数目
		int shibingNum;		//士兵数目


	/* data */
};


class Caretakerr  //备忘录模式中的,存档管理,就像游戏中的管理16个存档的对象
{
public:

	~Caretakerr()
	{


	};
	void SetStateMemento(Memento* pMemento,int index) { memento[index] = pMemento; }
	Memento *GetStateMemento(int index) { return memento[index] ; }

private:
	Memento* memento[16];

		/* data */
};




int main(int argc, char const *argv[])
{
	Originator* liubei=new Originator();//创建一个刘备
	Caretakerr pCaretaker;
	pCaretaker.SetStateMemento(liubei->SaveState(),1);       //存档到第一栏
	liubei->showState();

	liubei->SometimeLater();
	pCaretaker.SetStateMemento(liubei->SaveState(),2);      //一段时间后 存档到第二栏
	liubei->showState();

	liubei->LoadState(pCaretaker.GetStateMemento(1));		 //读取第一栏档
	liubei->showState();

	liubei->LoadState(pCaretaker.GetStateMemento(2));		 //读取第二栏档
	liubei->showState();

	liubei->SometimeLater();
	liubei->SometimeLater();
	pCaretaker.SetStateMemento(liubei->SaveState(),1);      //一段时间后 存档到第一栏
	liubei->LoadState(pCaretaker.GetStateMemento(1));		 //读取第一栏档
	liubei->showState();
}


 

设计模式之:备忘录模式