1.Memento 模式的关键是在不破坏封装的前提下,捕获并保存一个类的内部状态,这样就可以利用该保存的状态实施恢复操作。
2.Memento 模式结构图
3.实现
1 #ifndef _MEMENTO_H_ 2 #define _MEMENTO_H_ 3 4 #include <string> 5 using namespace std; 6 class Memento; 7 8 class Originator 9 { 10 public: 11 typedef string State; 12 Originator(); 13 Originator(const State& sdt); 14 ~Originator(); 15 Memento* CreateMemento(); 16 void SetMemento(Memento* men); 17 void RestoreToMemento(Memento* mt); 18 State GetState(); 19 void SetState(const State& sdt); 20 void PrintState(); 21 protected: 22 private: 23 State _sdt; 24 Memento* _mt; 25 }; 26 27 class Memento 28 { 29 public: 30 protected: 31 private: 32 //这是最关键的地方,将Originator为friend类,可以访问内部信息,但是其他类不能访问 33 friend class Originator; 34 typedef string State; 35 Memento(); 36 Memento(const State& sdt); 37 ~Memento(); 38 void SetState(const State& sdt); 39 State GetState(); 40 41 private: 42 State _sdt; 43 }; 44 45 #endif
1 #include "Memento.h" 2 #include <iostream> 3 4 using namespace std; 5 typedef string State; 6 7 Originator::Originator() 8 { 9 _sdt = ""; 10 _mt = 0; 11 } 12 Originator::Originator(const State& sdt) 13 { 14 _sdt = sdt; 15 _mt = 0; 16 } 17 Originator::~Originator() 18 { 19 20 } 21 Memento* Originator::CreateMemento() 22 { 23 return new Memento(_sdt); 24 } 25 State Originator::GetState() 26 { 27 return _sdt; 28 } 29 void Originator::SetState(const State& sdt) 30 { 31 _sdt = sdt; 32 } 33 void Originator::PrintState() 34 { 35 cout<<this->_sdt<<"....."<<endl; 36 } 37 void Originator::SetMemento(Memento* men) 38 { 39 40 } 41 void Originator::RestoreToMemento(Memento* mt) 42 { 43 this->_sdt = mt->GetState(); 44 } 45 //class Memento 46 Memento::Memento() 47 { 48 49 } 50 Memento::Memento(const State& sdt) 51 { 52 _sdt = sdt; 53 } 54 State Memento::GetState() 55 { 56 return _sdt; 57 } 58 void Memento::SetState(const State& sdt) 59 { 60 _sdt = sdt; 61 }
1 #include "Memento.h" 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc,char* argv[]) 6 { 7 Originator* o = new Originator(); 8 o->SetState("old"); //备忘前状态 9 o->PrintState(); 10 Memento* m = o->CreateMemento(); //将状态备忘 11 o->SetState("new"); //修改状态 12 o->PrintState(); 13 o->RestoreToMemento(m); //恢复修改前状态 14 o->PrintState(); 15 return 0; 16 }
4.代码说明
Memento模式的关键就是friend class Originator;我们可以看到,Memento的接口都声明为private,而将Originator声明为Memento的友元类。我们将Originator的状态保存在Memento类中,而将Memento接口private起来,也就达到了封装的功效。
在Originator类中我们提供了方法让用户后悔:RestoreToMemento(Memento* mt)我们可以通过这个接口让用户后悔。