设计模式笔记--行为型模式之六--Memento 备忘录

 

意图:

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

 

适用性:

1必须保存一个对象在某一个时刻的部分状态,这样以后需要时才能恢复到先前的状态

2如果用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

 

效果:

1保持封装边界   使用备忘录可以避免暴露一些只应由原发器管理却又必须储存在原发器之外的信息。

2简化了原发器   让客户管理它们请求的状态会简化Originator,并且使得客户工作结束时无需通知原发器

3使用 Memento可能代价很高  如果原发器在生成备忘录时必须拷贝并储存大量的信息,或者客户非常频繁地创建备忘录,可能会导致非常大的开销

4定义宽接口和窄接口

 

实现:

1语言支持  Memento有两个接口,一个为原发器所使用的宽接口,一个为其它对象所使用的窄接口。在C++中,可将Originator作为Memento的一个友元,并使接口为私有。只有窄接口被声明为公共的。

2存储式增量改变

如果备忘录的创建及返回的顺序是可测的,备忘录可以仅存储原发器内部状态的增量改变

 

 

The code is below.

Memento.h

  1. #include <string>
  2. #include <iostream>
  3. using namespace std;
  4. #define MAX_NUM 30
  5. class Point
  6. {
  7. public:
  8.     Point(int x, int y):_x(x),_y(y)
  9.     {
  10.       cout<<"Create a point, x is" <<_x<<", y is"<<_y<<endl;
  11.     }
  12. private:
  13.     int _x,_y;
  14. };
  15. class ConstraintSolverMemento;
  16. class MoveCommand
  17. {
  18. public:
  19.     MoveCommand() 
  20.     {cout<<"Create a move command"<<endl;
  21.      for(int i=0;i<MAX_NUM;i++)
  22.          _state[i]=0;
  23.     }
  24.     void Execute(string s);
  25.     void Unexecute();
  26. private:
  27.     ConstraintSolverMemento* _state[MAX_NUM];
  28.     //Point _delta;
  29. };
  30. class ConstraintSolver
  31. {
  32. public:
  33.     static ConstraintSolver* Instance();
  34.     void   solve() {cout<<"Solve it"<<endl;}
  35.     void   AddConstraint()    {cout<<"Add constraint."<<endl;}
  36.     void   RemoveConstraint() {cout<<"Remove constraint."<<endl;}
  37.     ConstraintSolverMemento*   CreateMemento(string s);
  38.     void SetMemento(ConstraintSolverMemento*);
  39. private:
  40.     static ConstraintSolver* _instance;
  41. };
  42. class ConstraintSolverMemento
  43. {
  44. public:
  45.     virtual ~ConstraintSolverMemento(){cout<<"Destory ConstraintSolverMemento"<<endl;}
  46.     string getstate(){return state;}
  47. private:
  48.     friend class ConstraintSolver;
  49.     ConstraintSolverMemento(string s):state(s){}
  50.     string state;
  51. };

 

Memento.cpp

 

 

  1. #include "Memento.h"
  2. #include <iostream>
  3. #include <string>
  4. using namespace std;
  5. ConstraintSolver* ConstraintSolver::_instance = 0;
  6. Constrai ConstraintSolverMemento(s);
  7. }
  8. void ConstraintntSolver* ConstraintSolver::Instance()
  9. {
  10.     if (_instance == 0)
  11.         _instance = new ConstraintSolver;
  12.     return _instance;
  13. }
  14. ConstraintSolverMemento* ConstraintSolver::CreateMemento(string s)
  15. {
  16.     cout<<"Create Memento"<<endl;
  17.     return newSolver::SetMemento(ConstraintSolverMemento* s)
  18. {
  19.     cout<<"Set Memento "<<s->getstate()<<endl;
  20.     
  21. }
  22. void MoveCommand::Execute(string s)
  23. {
  24.     ConstraintSolver* solver = ConstraintSolver::Instance();
  25.     for (int i=0;i<MAX_NUM;i++)
  26.         if ( _state[i] == 0)
  27.              break;
  28.     if(i<MAX_NUM)
  29.     {
  30.      _state[i] =solver->CreateMemento(s);
  31.      cout<<"Execute " << i<<endl;
  32.     }
  33.     solver->solve();
  34. }
  35. void MoveCommand::Unexecute()
  36. {
  37.     ConstraintSolver* solver = ConstraintSolver::Instance();
  38.     for(int i=MAX_NUM-1;i>=0;i--)
  39.         if(_state[i]!=0 )
  40.             break;
  41.     cout<<"unExecute " << i<<endl;
  42.     if (i>=1)
  43.      solver->SetMemento(_state[i-1]);
  44.     else
  45.       cout<<"Return back orginal state"<<endl;
  46.     _state[i] = 0;
  47.     solver->solve();
  48. }

main.cpp

 

  1. #include "Memento.h"
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6.     MoveCommand a;
  7.     string s="down";
  8.     a.Execute("down");
  9.     a.Execute("up");
  10.     a.Unexecute();
  11.     a.Unexecute();
  12.     return 0;
  13. }

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值