您的位置:首页 > 编程语言 > Qt开发

设计模式 备忘录模式

2011-09-12 10:52 302 查看
1、memento.h

#ifndef MEMENTO_H
#define MEMENTO_H

#include <iostream>
#include <vector>
using namespace std;

class Memento;
class Employee //原发器(Originator),创建一个备忘录. 用以记录当前时刻它的内部状态.使用备忘录恢复内部状态.
{
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;
};

class Memento //Memento(备忘录),存储原发器对象的内部状态,防止原发器以外的对象访问备忘录.
{
public:
Memento(int, char*, double);
virtual ~Memento();
friend class Employee;//声明为友元类,可以访问这个类的成员变量,就是说,在Employee成员函数中有Memento对象,
//则,可以引用Memento对象的私有变量,如m_nId
private:
int m_nId;
char* m_pName;
double m_dSalary;
};

class Caretaker //看管者(caretaker),负责保存好备忘录,不能对备忘录的内容操作或检查.
{
public:
Caretaker(Employee*);
virtual ~Caretaker();
void SaveEmployee();
void UnsaveEmployee();
private:
std::vector<Memento*> m_vMementos;
Employee* m_pEmployee;
};

#endif // MEMENTO_H
2、memento.cpp

#include "memento.h"

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 << "ID:" << employee.m_nId << ", "
<< "Name:" << employee.m_pName << ", "
<< "Salary:" << employee.m_dSalary << endl;
}

Memento::Memento(int nId, char* pName, double dSalary)
{
m_nId = nId;
m_pName = pName;
m_dSalary = dSalary;
}

Memento::~Memento(){}

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);
}
}
3、main.cpp
/*
作者:jhluroom弹   QQ:454676244  MSN:jhlu0815@hotmail.com
开发IDE:qt creater
开发环境:QT C++
参考网站:神秘果:http://www.shenmiguo.com/

定义:
在不破坏封装性的前提下.捕获一个对象的内部状态. 并在该对象之外保存这个状态.这样以后就可以将该对象恢复到以前保存的状态.

理解:
1.备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”
的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录
提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。
2.备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。
3.备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作或检查。

要点:
1.备忘录模式(Memento)的定义为:在不破坏封闭的前提下,捕获并保存一个对象的内部状态,这样可以将对象恢复到原先的状态。
2.很多应用程序中的Ctrl+Z会取消最后一次用户操作,如果不用备忘模式,看管者(caretaker)对象要备份原发器(Originator)
对象状态,并且要清楚原发器内部的结构,这样在原发器上的任何修改,看管者都要做相应的修改,使用备记录模式可以解决这种问题,
备忘录封闭保存备份的状态,当原发器提出备份请求,它就会创建一个备忘录对象返回给看者。
3.Memento模式中封装的是需要保存的状态,当需要恢复的时候才取出来进行恢复。原理很简单,实现的时候需要注意一个地方:
窄接口和宽接口。
宽接口,就是一般意义上的接口,把对外的接口作为public成员;
窄接口,把接口作为private成员,而把需要访问这些接口函数的类作为这个类的友元类,也就是说接口只暴露给了对这些接口感兴趣的类,
而不是暴露在外部。

应用:
1.需要保存一个对象在某时刻的状态.以备以后恢复.
2.保存状态时不想让其它对象直接得到对象内部的实现细节。
3.假设有一雇员信息,我们可对其进行修改,当多次修改后,想撤消回原来的状态,这时可以用备忘录模式对雇员信息进行备份,
需要还原时就可对其进行撤消操作。如下面程序所示:

以上文字说明,从网上整理而来,有可能部分与其他同仁相同,请谅解,希望我们能够共同交流,谢谢!
*/

#include <QtCore/QCoreApplication>

#include "memento.h"

int main(int argc, char *argv[])
{
cout << "=== jhluroom start ========" << endl;

Employee* pEmployee = new Employee();
Caretaker* pCaretaker = new Caretaker(pEmployee);

pEmployee->SetId(1);
pEmployee->SetName("xiao li");
pEmployee->SetSalary(6000.00);
pCaretaker->SaveEmployee();
cout <<"撤消前: "<< *pEmployee;

pEmployee->SetId(2);
pEmployee->SetName("xiao wang");
pEmployee->SetSalary(8000.00);
pCaretaker->SaveEmployee();
cout <<"撤消前: "<< *pEmployee;

pEmployee->SetId(3);
pEmployee->SetName("xiao lu");
pEmployee->SetSalary(15000.00);
pCaretaker->SaveEmployee();
cout <<"撤消前: "<< *pEmployee;

pCaretaker->UnsaveEmployee();
cout << "撤消后: " << *pEmployee;
pCaretaker->UnsaveEmployee();
cout << "撤消后: " << *pEmployee;
pCaretaker->UnsaveEmployee();
cout << "撤消后: " << *pEmployee;

cout << "=== jhluroom finish _^_ ===" << endl;
return 0;
}


运行结果:
=== jhluroom start ========

撤消前: ID:1, Name:xiao li, Salary:6000

撤消前: ID:2, Name:xiao wang, Salary:8000

撤消前: ID:3, Name:xiao lu, Salary:15000

撤消后: ID:3, Name:xiao lu, Salary:15000

撤消后: ID:2, Name:xiao wang, Salary:8000

撤消后: ID:1, Name:xiao li, Salary:6000
=== jhluroom finish _^_ ===
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息