0 引言

0.1 目的

       本文档给出设计模式之——Memento模式的简化诠释,并给出其C++实现

0.2 说明

Project

Design Pattern ExplanationBy K_Eckel

Authorization

Free Distributed but Ownership Reserved

Date

2005-04-05Cherry blossom is Beautiful

Test Bed

MS Visual C++ 6.0

0.3 参考

       在本文档的写作中,参考了以下的资源,在此列出表示感谢:

u       书籍

[GoF 2000]GoF,Design Patterns-Elements of Reusable Object-Oriented Software

Addison-Wesley 2000/9.

        [Martine 2003]Robert C.Martine, Agile Software Development Principles, Patterns, and Practices, Pearson Education, 2003.

0.4 联系作者

Author

K_Eckel

State

Candidate for Master’s Degree School of Computer Wuhan University

E_mail

frwei@whu.edu.cn  

2 Memento模式

2.1 问题

没有人想犯错误,但是没有人能够不犯错误。犯了错误一般只能改过,却很难改正(恢复)。世界上没有后悔药,但是我们在进行软件系统的设计时候是要给用户后悔的权利(实际上可能也是用户要求的权利:)),我们对一些关键性的操作肯定需要提供诸如撤销(Undo)的操作。那这个后悔药就是Memento模式提供的。

2.2 模式选择

       Memento模式的关键就是要在不破坏封装行的前提下,捕获并保存一个类的内部状态,这样就可以利用该保存的状态实施恢复操作。为了达到这个目标,可以在后面的实现中看到我们采取了一定语言支持的技术。Memento模式的典型结构图为:


2-1Memento Pattern结构图

2.3 实现

2.3.1 完整代码示例(code

       Memento模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用C++实现,并在VC 6.0下测试运行)。
 

代码片断1Memento.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:
 //
这是最关键的地方,将Originatorfriend类,可以访问内部信息,但是其他类不能访问
 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_

代码片断2Memento.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;
}

 

代码片断3main.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;
}

 


2.3.2 代码说明

       Memento模式的关键就是friend class Originator;我们可以看到,Memento的接口都声明为private,而将Originator声明为Memento的友元类。我们将Originator的状态保存在Memento类中,而将Memento接口private起来,也就达到了封装的功效。

       Originator类中我们提供了方法让用户后悔:RestoreToMemento(Memento* mt);我们可以通过这个接口让用户后悔。在测试程序中,我们演示了这一点:Originator的状态由old变为new最后又回到了old

2.4 讨论

       Command模式中,Memento模式经常被用来维护可以撤销(Undo)操作的状态。这一点将在Command模式具体说明。

Posted on 2005-07-08 20:49  k_eckel's mindview  阅读(575)  评论(0)    收藏  举报