示例问题:
类似于虚拟机的快照功能,编写一个能够记录对象运行过程中状态的功能,用以日后恢复某种状态。
分析:
能够保存不同阶段的状态,并用以恢复。不能对调用程序暴露备份的细节。
解决方案:
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++实现)(总)