设计模式-备忘录模式
备忘录模式(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 ;
}
#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