首页 > 代码库 > 备忘录模式

备忘录模式

备忘录模式定义

备忘录模式(Memento),在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将对象回复到原先保存的状态。

备忘录模式结构图

备忘录模式结构图如下所示:

图 01 备忘录模式结构图

备忘录模式套用代码

  1 #include "iostream"  2 using namespace std;  3 #include <string>  4   5 // 备忘录类,用于保存数据  6 class Memento  7 {  8 private:  9     string state; 10 public: 11     Memento(string state) 12     { 13         this->state = state; 14     } 15  16     // 获得保存的属性数据,可以是多个 17     string GetState() 18     { 19         return this->state; 20     } 21 }; 22  23 // 发起人类,需要备份数据的类 24 class Originator 25 { 26 private: 27     // 需要保存的属性,可能有多个 28     string state; 29 public: 30     void SetState(string state) 31     { 32         this->state = state; 33     } 34  35     string GetState() 36     { 37         return this->state; 38     } 39      40     // 创建备忘录,将当前需要保存的信息导入并实例化一个Memento对象 41     Memento* CreateMemento() 42     { 43         return (new Memento(state)); 44     } 45  46     // 恢复备忘录,将Memento导入并将相关数据恢复 47     void SetMemento(Memento* memento) 48     { 49         this->state = memento->GetState(); 50     } 51      52     // 显示数据 53     void Show() 54     { 55         cout << "state = " << this->state << endl; 56     } 57  58 }; 59  60 // 管理者类,将备忘录对象保存起来 61 class Caretaker 62 { 63 private: 64     Memento* memento; 65 public: 66     Memento* GetMemento() 67     { 68         return this->memento; 69     } 70  71     void SetMemento(Memento* memento) 72     { 73         this->memento = memento; 74     } 75  76     virtual ~Caretaker() 77     { 78         if(memento != NULL) 79         { 80             delete memento; 81             memento = NULL; 82         } 83     } 84 }; 85  86 void main() 87 { 88     Originator* o = new Originator(); 89     o->SetState("On"); 90     o->Show(); 91  92     Caretaker* c = new Caretaker(); 93     c->SetMemento(o->CreateMemento()); 94  95     o->SetState("off"); 96     o->Show(); 97  98     o->SetMemento(c->GetMemento()); 99     o->Show();100 101     if (o != NULL)102     {103         delete o;104         o = NULL;105     }106 107     if (c != NULL)108     {109         delete c;110         c = NULL;111     }112 }

 

备忘录模式特点

① 把要保存的细节给封装在了Memento中,哪一天要更改保存的细节也不用影响客户端。

② 备忘录模式比较适用于功能比较复杂的,但需要维护属性历史的类,或者需要保存的属性只是众多属性中的一小部分量,Originator可以根据保存的Memento信息还原到前一状态。

③ 如果在摸个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。

④ 使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。

⑤ 当角色的状态改变的时候,有可能这个状态无效,这时候可以使用暂时存储起来的备忘录将状态复原。

备忘录模式实例应用

备忘录模式实例应用类图

图 02 备忘录模式实例应用类图

备忘录模式实例应用代码

  1 #include "iostream"  2 using namespace std;  3 #include <string>  4   5 // 备忘录类,用于保存数据  6 class CRoleStateMemento  7 {  8 private:  9     int vit; 10     int atk; 11     int def; 12 public: 13     CRoleStateMemento(int vit, int atk, int def) 14     { 15         this->vit = vit; 16         this->atk = atk; 17         this->def = def; 18     } 19      20     int GetVit() 21     { 22         return this->vit; 23     } 24  25     void SetVit(int vit) 26     { 27         this->vit; 28     } 29  30     int GetAtk() 31     { 32         return this->atk; 33     } 34  35     void SetAtk(int atk) 36     { 37         this->atk = atk; 38     } 39  40     int GetDef() 41     { 42         return this->def; 43     } 44  45     void SetDef(int def) 46     { 47         this->def = def; 48     } 49 }; 50  51 // 发起人类,需要备份数据的类 52 class CGameRole 53 { 54 private: 55     // 需要保存的属性 56     int vit; 57     int atk; 58     int def; 59 public: 60     int GetVit() 61     { 62         return this->vit; 63     } 64  65     void SetVit(int vit) 66     { 67         this->vit; 68     } 69  70     int GetAtk() 71     { 72         return this->atk; 73     } 74  75     void SetAtk(int atk) 76     { 77         this->atk = atk; 78     } 79  80     int GetDef() 81     { 82         return this->def; 83     } 84  85     void SetDef(int def) 86     { 87         this->def = def; 88     } 89      90     // 设置初始化的属性值 91     void SetInitState() 92     { 93         this->vit = 100; 94         this->atk = 100; 95         this->def = 100; 96     } 97  98     // 创建备忘录,将当前需要保存的信息导入并实例化一个CRoleStateMemento对象 99     CRoleStateMemento* CreateRoleStateMemento()100     {101         return (new CRoleStateMemento(vit, atk, def));102     }103 104     // 恢复备忘录,将CRoleStateMemento导入并将相关数据恢复105     void SetRoleStateMemento(CRoleStateMemento* roleStateMemento)106     {107         this->vit = roleStateMemento->GetVit();108         this->atk = roleStateMemento->GetAtk();109         this->def = roleStateMemento->GetDef();110     }111     112     void Fight()113     {114         this->vit = 0;115         this->atk = 2;116         this->def = 100;117     }118     // 显示数据119     void ShowState()120     {121         cout << "vit = " << vit << endl;122         cout << "atk = " << atk << endl; 123         cout << "def = " << def << endl;124     }125 126 };127 128 // 管理者类,将备忘录对象保存起来129 class CRoleStateCaretaker130 {131 private:132     CRoleStateMemento* roleStateMemento;133 public:134     CRoleStateMemento* GetRoleStateMemento()135     {136         return this->roleStateMemento;137     }138 139     void SetRoleStateMemento(CRoleStateMemento* roleStateMemento)140     {141         this->roleStateMemento = roleStateMemento;142     }143 144     virtual ~CRoleStateCaretaker()145     {146         if(roleStateMemento != NULL)147         {148             delete roleStateMemento;149             roleStateMemento = NULL;150         }151     }152 };153 154 void main()155 {156     // 战斗开始前的属性值157     cout << "战斗开始前的属性值" << endl;158     CGameRole* xiaoyun = new CGameRole();159     xiaoyun->SetInitState();160     xiaoyun->ShowState();161 162     // 将当前属性值保存起来163     CRoleStateCaretaker* caretaker = new CRoleStateCaretaker();164     caretaker->SetRoleStateMemento(xiaoyun->CreateRoleStateMemento());165     166     167     // 战斗结束后168     cout << "战斗中牺牲" << endl;169     xiaoyun->Fight();170     xiaoyun->ShowState();171 172     // 恢复之前的属性值173     cout << "属性值恢复" << endl;174     xiaoyun->SetRoleStateMemento(caretaker->GetRoleStateMemento());175     xiaoyun->ShowState();176 177     if (xiaoyun != NULL)178     {179         delete xiaoyun;180         xiaoyun = NULL;181     }182 183     if (caretaker != NULL)184     {185         delete caretaker;186         caretaker = NULL;187     }188 }

2014-12-04   11:33:16

 

备忘录模式