備忘錄模式(Memento)的定義為:在不破壞封閉的前提下,捕獲并保存一個對象的內(nèi)部狀態(tài),這樣可以將對象恢復(fù)到原先的狀態(tài)。
很多應(yīng)用程序中的Ctrl+Z會取消最后一次用戶操作,如果不用備忘模式,看管者(caretaker)對象要備份原發(fā)器(Originator)對象狀態(tài),并且要清楚原發(fā)器內(nèi)部的結(jié)構(gòu),這樣在原發(fā)器上的任何修改,看管者都要做相應(yīng)的修改,使用備記錄模式可以解決這種問題,備忘錄封閉保存?zhèn)浞莸臓顟B(tài),當(dāng)原發(fā)器提出備份請求,它就會創(chuàng)建一個備忘錄對象返回給看者。結(jié)構(gòu)圖為:

假設(shè)有一雇員信息,我們可對其進(jìn)行修改,當(dāng)多次修改后,想撤消回原來的狀態(tài),這時可以用備忘錄模式對雇員信息進(jìn)行備份,需要還原時就可對其進(jìn)行撤消操作。
實現(xiàn)代碼:
//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;
}
我們建立了一個雇員,對其進(jìn)行了三次修改,最后一次沒有備忘,所以在進(jìn)行兩次撤消后,雇員信息還原成為初始信息。
程序最后輸出為:
編號:1 姓名:張三 工資:8000
編號:1 姓名:李四 工資:8000
編號:1 姓名:李四 工資:10000
撤消后:編號:1 姓名:李四 工資:8000
撤消后:編號:1 姓名:張三 工資:8000