设计模式(C++实现)(十)——备忘录模式

示例问题:

类似于虚拟机的快照功能,编写一个能够记录对象运行过程中状态的功能,用以日后恢复某种状态。

分析:

能够保存不同阶段的状态,并用以恢复。不能对调用程序暴露备份的细节。

解决方案:

MyClass.h

实现了需要备忘的类CMyClass(主要使用的类),备忘录类CMemento(记录重要数据),备忘录管理类CMementoManager(管理各个阶段的备忘录)

#pragma once

#include <string>
#include <map>
#include <iostream>

//备忘录
class CMemento
{
public:
	CMemento(int iDataA, std::string strDataB, std::string strDataC)
		: m_iDataA(iDataA)
		, m_strDataB(strDataB)
		, m_strDataC(strDataC)
	{

	}

	virtual ~CMemento()
	{

	}

	int m_iDataA;
	std::string m_strDataB;
	std::string m_strDataC;
};

//需要备忘的类
class CMyClass
{
public:
	CMyClass()
	{

	}

	virtual ~CMyClass()
	{

	}

	CMemento* CreateMemento()
	{
		return new(std::nothrow) CMemento(m_iImportantDataA, m_strImportantDataB, m_strImportantDataC);
	}

	void SetMemento(CMemento* pMemento)
	{
		if (nullptr != pMemento)
		{
			m_iImportantDataA = pMemento->m_iDataA;
			m_strImportantDataB = pMemento->m_strDataB;
			m_strImportantDataC = pMemento->m_strDataC;
		}
	}

	void SetCommonDataA(int iCommonDataA)
	{
		m_iCommonDataA = iCommonDataA;
	}

	void SetCommonDataB(std::string strCommonDataB)
	{
		m_strCommonDataB = strCommonDataB;
	}

	void SetCommonDataC(std::string strCommonDataC)
	{
		m_strCommonDataC = strCommonDataC;
	}

	void SetImportantDataA(int iImportantDataA)
	{
		m_iImportantDataA = iImportantDataA;
	}

	void SetImportantDataB(std::string strImportantDataB)
	{
		m_strImportantDataB = strImportantDataB;
	}

	void SetImportantDataC(std::string strImportantDataC)
	{
		m_strImportantDataC = strImportantDataC;
	}

	void PrintData()
	{
		std::cout << "通用数据A : " << m_iCommonDataA << std::endl;
		std::cout << "通用数据B : " << m_strCommonDataB << std::endl;
		std::cout << "通用数据C : " << m_strCommonDataC << std::endl;
		std::cout << "重要数据A : " << m_iImportantDataA << std::endl;
		std::cout << "重要数据B : " << m_strImportantDataB << std::endl;
		std::cout << "重要数据C : " << m_strImportantDataC << std::endl;
	}

private:

	//通用数据,记录状态时不备份该数据
	int m_iCommonDataA;
	std::string m_strCommonDataB;
	std::string m_strCommonDataC;

	//记录状态时需要备份的数据
	int m_iImportantDataA;
	std::string m_strImportantDataB;
	std::string m_strImportantDataC;
};

//备忘录管理
class CMementoManager
{
public:
	CMementoManager()
	{

	}

	virtual ~CMementoManager()
	{

	}

	//添加备忘,备忘数据和时间对应
	void AddMemento(std::string strTime, CMemento* pMemento)
	{
		if (nullptr != pMemento)
		{
			m_mapMemento[strTime] = pMemento;
		}
	}

	//删除对应事件的备忘
	void DelMemento(std::string strTime)
	{
		m_mapMemento.erase(strTime);
	}

	//查找备忘
	CMemento* GetMemto(std::string strTime)
	{
		return m_mapMemento[strTime];
	}

	//清除所有备忘录
	void ClearMemento()
	{
		std::map<std::string, CMemento*>::iterator itor = m_mapMemento.begin();
		for (; itor != m_mapMemento.end(); ++itor)
		{
			if (nullptr != itor->second)
			{
				delete itor->second;
				itor->second = nullptr;
			}
		}
		m_mapMemento.clear();
	}

private:
	std::map<std::string, CMemento*> m_mapMemento;
};

main.cpp

// main.cpp : Defines the entry point for the console application.
//

#include "MyClass.h"


int main()
{
	CMyClass MyClass;
	CMementoManager MementoMgr;
	MyClass.SetCommonDataA(10);
	MyClass.SetCommonDataB("Common_B");
	MyClass.SetCommonDataC("Common_C");

	MyClass.SetImportantDataA(11);
	MyClass.SetImportantDataB("ImportantDataB_1");
	MyClass.SetImportantDataC("ImportantDataC_1");
	MementoMgr.AddMemento("第一天", MyClass.CreateMemento());

	MyClass.SetImportantDataA(22);
	MyClass.SetImportantDataB("ImportantDataB_2");
	MyClass.SetImportantDataC("ImportantDataC_2");
	MementoMgr.AddMemento("第二天", MyClass.CreateMemento());

	MyClass.SetImportantDataA(33);
	MyClass.SetImportantDataB("ImportantDataB_3");
	MyClass.SetImportantDataC("ImportantDataC_3");
	MementoMgr.AddMemento("第三天", MyClass.CreateMemento());

	MyClass.SetImportantDataA(44);
	MyClass.SetImportantDataB("ImportantDataB_4");
	MyClass.SetImportantDataC("ImportantDataC_4");

	std::cout << "第一天的数据" << std::endl;
	MyClass.SetMemento(MementoMgr.GetMemto("第一天"));
	MyClass.PrintData();

	std::cout << "第二天的数据" << std::endl;
	MyClass.SetMemento(MementoMgr.GetMemto("第二天"));
	MyClass.PrintData();

	std::cout << "第三天的数据" << std::endl;
	MyClass.SetMemento(MementoMgr.GetMemto("第三天"));
	MyClass.PrintData();

	system("pause");
    return 0;
}

结果

备忘录模式的使用:

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

备忘录模式比较适用于功能比较复杂的,但需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分。

备忘录模式,将备忘的过程屏蔽起来,对使用者(使用被备忘的类)不可见。修改备忘数据时,使用者也不需要做出改变。

何时使用备忘录模式:

备忘录模式比较适用于功能比较复杂的,但需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分。

 

返回目录:设计模式(C++实现)(总)

上一篇:设计模式(C++实现)(九)——状态模式

下一篇:设计模式(C++实现)(十一)——建造者模式

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值