C++备忘录模式
<上一节
下一节>
由遇到的问题引出备忘录模式
没有人想犯错误,但是没有人能够不犯错误。犯了错误一般只能改过,却很难改正(恢复)。世界上没有后悔药,但是我们在进行软件系统的设计时候是要给用户后悔的权利(实际上可能也是用户要求的权利:)),我们对一些关键性的操作肯定需要提供诸如撤销(Undo)的操作。那这个后悔药就是备忘录模式提供的。模式选择
备忘录模式的关键就是要在不破坏封装行的前提下,捕获并保存一个类的内部状态,这样就可以利用该保存的状态实施恢复操作。为了达到这个目标,可以在后面的实现中看到我们采取了一定语言支持的技术。备忘录模式的典型结构图为:图 2-1:备忘录模式结构图
备忘录模式的实现
完整代码示例(code):备忘录模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 VC 6.0 下测试运行)。代码片断 1:Memento.h
//Memento.h
#ifndef _MEMENTO_H_
#define _MEMENTO_H_
#include <string>
using namespace std;
class Memento;
class Originator{
public:
typedef string State;
Originator();
Originator(const State& sdt);
~Originator();
Memento* CreateMemento();
void SetMemento(Memento* men);
void RestoreToMemento(Memento* mt);
State GetState();
void SetState(const State& sdt);
void PrintState();
protected:
private:
State _sdt;
Memento* _mt;
};
class Memento{
public:
protected:
private:
//这是最关键的地方,将 Originator 为 friend 类,可以访问内部信息,但是其他类不能访问
friend class Originator;
typedef string State;
Memento();
Memento(const State& sdt);
~Memento();
void SetState(const State& sdt);
State GetState();
private:
State _sdt;
};
#endif //~_MEMENTO_H_
代码片断 2:Memento.cpp
//Memento.cpp
#include "Memento.h"
#include <iostream>
using namespace std;
typedef string State;
Originator::Originator(){
_sdt = "";
_mt = 0;
}
Originator::Originator(const State& sdt){
_sdt = sdt;
_mt = 0;
}
Originator::~Originator(){
}
Memento* Originator::CreateMemento(){
return new Memento(_sdt);
}
State Originator::GetState(){
return _sdt;
}
void Originator::SetState(const State& sdt){
_sdt = sdt;
}
void Originator::PrintState(){
cout<<this->_sdt<<"....."<<endl;
}
void Originator::SetMemento(Memento* men){
}
void Originator::RestoreToMemento(Memento* mt){
this->_sdt = mt->GetState();
}
//class Memento
Memento::Memento(){
}
Memento::Memento(const State& sdt){
_sdt = sdt;
}
State Memento::GetState(){
return _sdt;
}
void Memento::SetState(const State& sdt){
_sdt = sdt;
}
代码片断 3:main.cpp
//main.cpp
#include "Memento.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[]){
Originator* o = new Originator();
o->SetState("old"); //备忘前状态
o->PrintState();
Memento* m = o->CreateMemento(); //将状态备忘
o->SetState("new"); //修改状态
o->PrintState();
o->RestoreToMemento(m);
o->PrintState();
return 0;
//恢复修改前状态
}
代码说明:备忘录模式的关键就是 friend class Originator;我们可以看到,备忘录的接口都声明为 private,而将 Originator 声明为备忘录的友元类。我们将 Originator 的状态保存在备忘录类中,而将备忘录接口 private 起来,也就达到了封装的功效。
在 Originator 类中我们提供了方法让用户后悔:RestoreToMemento(Memento* mt);我们可以通过这个接口让用户后悔。在测试程序中,我们演示了这一点:Originator 的状态由 old 变为 new 最后又回到了 old。
关于备忘录模式的讨论
在命令模式中,备忘录模式经常被用来维护可以撤销(Undo)操作的状态。这一点将在命令模式具体说明。
<上一节
下一节>