备忘录模式(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