备忘录模式(Memento)的定义为:在不破坏封闭的前提下,捕获并保存一个对象的内部状态,这样可以将对象恢复到原先的状态。
很多应用程序中的Ctrl+Z会取消最后一次用户操作,如果不用备忘模式,看管者(caretaker)对象要备份原发器(Originator)对象状态,并且要清楚原发器内部的结构,这样在原发器上的任何修改,看管者都要做相应的修改,使用备记录模式可以解决这种问题,备忘录封闭保存备份的状态,当原发器提出备份请求,它就会创建一个备忘录对象返回给看者。结构图为:
假设有一雇员信息,我们可对其进行修改,当多次修改后,想撤消回原来的状态,这时可以用备忘录模式对雇员信息进行备份,需要还原时就可对其进行撤消操作。
实现代码:
//Employee.h
#include <iostream>
class Memento;
class Employee
{
public:
Employee();
virtual ~Employee();
void SetId(int);
int GetId();
char* GetName();
void SetName(char*);
void SetSalary(double);
double GetSalary();
void SetMemento(Memento*);
Memento* GetMemento();
friend std::ostream& operator<<(std::ostream& os, Employee& employee);
private:
int m_nId;
char* m_pName;
double m_dSalary;
};
//Employee.cpp
#include "stdafx.h"
#include "Employee.h"
#include "Memento.h"
using namespace std;
Employee::Employee()
{
}
Employee::~Employee()
{
}
void Employee::SetId(int nId)
{
m_nId = nId;
}
int Employee::GetId()
{
return m_nId;
}
void Employee::SetName(char* pName)
{
m_pName = pName;
}
char* Employee::GetName()
{
return m_pName;
}
void Employee::SetSalary(double dSalary)
{
m_dSalary = dSalary;
}
double Employee::GetSalary()
{
return m_dSalary;
}
void Employee::SetMemento(Memento* pMemento)
{
m_nId = pMemento->m_nId;
m_pName = pMemento->m_pName;
m_dSalary = pMemento->m_dSalary;
}
Memento* Employee::GetMemento()
{
return new Memento(m_nId, m_pName, m_dSalary);
}
std::ostream& operator<<(std::ostream& os, Employee& employee)
{
return os << "编号:" << employee.m_nId << " "
<< "姓名:" << employee.m_pName << " "
<< "工资:" << employee.m_dSalary << endl;
}
//Memento.h
class Memento
{
public:
Memento(int, char*, double);
virtual ~Memento();
friend class Employee;
private:
int m_nId;
char* m_pName;
double m_dSalary;
};
class Memento
{
public:
Memento(int, char*, double);
virtual ~Memento();
friend class Employee;
private:
int m_nId;
char* m_pName;
double m_dSalary;
};
//Memento.cpp
#include "stdafx.h"
#include "Memento.h"
Memento::Memento(int nId, char* pName, double dSalary)
{
m_nId = nId;
m_pName = pName;
m_dSalary = dSalary;
}
Memento::~Memento()
{
}
//Caretaker.h
#include <vector>
class Employee;
class Memento;
class Caretaker
{
public:
Caretaker(Employee*);
virtual ~Caretaker();
void SaveEmployee();
void UnsaveEmployee();
private:
std::vector<Memento*> m_vMementos;
Employee* m_pEmployee;
};
//Caretaker.cpp
#include "stdafx.h"
#include "Caretaker.h"
#include "Employee.h"
using namespace std;
Caretaker::Caretaker(Employee* pEmployee)
{
m_pEmployee = pEmployee;
}
Caretaker::~Caretaker()
{
if(m_pEmployee != NULL)
{
delete m_pEmployee;
m_pEmployee = NULL;
}
}
void Caretaker::SaveEmployee()
{
Memento* pMemento = m_pEmployee->GetMemento();
m_vMementos.push_back(pMemento);
}
void Caretaker::UnsaveEmployee()
{
if(m_vMementos.size() > 0)
{
Memento* pMemento = m_vMementos.at(m_vMementos.size() - 1);
m_vMementos.pop_back();
m_pEmployee->SetMemento(pMemento);
}
}
//main.cpp
#include "stdafx.h"
#include "Employee.h"
#include "Memento.h"
#include "Caretaker.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
Employee* pEmployee = new Employee;
pEmployee->SetId(1);
pEmployee->SetName("张三");
pEmployee->SetSalary(8000.00);
Caretaker* pCaretaker = new Caretaker(pEmployee);
pCaretaker->SaveEmployee();
cout << *pEmployee;
pEmployee->SetName("李四");
pCaretaker->SaveEmployee();
cout << *pEmployee;
pEmployee->SetSalary(10000);
cout << *pEmployee;
pCaretaker->UnsaveEmployee();
cout << "撤消后:" << *pEmployee;
pCaretaker->UnsaveEmployee();
cout << "撤消后:" << *pEmployee;
return 0;
}
我们建立了一个雇员,对其进行了三次修改,最后一次没有备忘,所以在进行两次撤消后,雇员信息还原成为初始信息。
程序最后输出为:
编号:1 姓名:张三 工资:8000
编号:1 姓名:李四 工资:8000
编号:1 姓名:李四 工资:10000
撤消后:编号:1 姓名:李四 工资:8000
撤消后:编号:1 姓名:张三 工资:8000