Hello,阳光柠檬! 养成记录笔记的好习惯

Memento模式

2016-02-26
C++

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

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_

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;
}

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;
}

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

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


上一篇 Mediator模式

下一篇 Strategy模式

Comments

Content