一,概述
定義:在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在該對象之外儲存這個狀態。這樣以後就可將該對象恢複到原先儲存的狀態。
1.Originator(發起人):負責建立一個備忘錄Memento,用以記錄當前時刻自身的內部狀態,並可使用備忘錄恢複內部狀態。Originator可以根據需要決定Memento儲存自己的哪些內部狀態。
2.Memento(備忘錄):負責儲存Originator對象的內部狀態,並可以防止Originator以外的其他對象訪問備忘錄。備忘錄有兩個介面:Caretaker只能看到備忘錄的窄介面,他只能將備忘錄傳遞給其他對象。Originator卻可看到備忘錄的寬介面,允許它訪問返回到先前狀態所需要的所有資料。
3.Caretaker(管理者):負責備忘錄Memento,不能對Memento的內容進行訪問或者操作。
二,基本代碼格式
#include <iostream>using namespace std; class Memento//備忘錄,儲存 Originator內部狀態 {private: string state;public: Memento(string state) { this->state = state; } string getState() { return state; }}; class Originator//發起人,建立備忘錄 {private: string state;public: string getState() { return state; } void setState(string value) { this->state = value; } Memento* CreateMemento()//建立備忘錄 { return (new Memento(state)); } void SetMemento(Memento *memento) { this->state = memento->getState(); } void Show()//顯示備忘錄狀態 { cout<<"State="<<state<<endl; } }; class Caretaker//管理者 {public: Memento *memento;public: Memento* getMemento()//返回備忘錄狀態 { return memento; } Memento* setMemento(Memento *mymemento)//設定備忘錄狀態 { this->memento=mymemento; } }; int main(){ Originator *o = new Originator();//發起人 o->setState("On"); o->Show(); Caretaker *c = new Caretaker();//管理者 c->setMemento(o->CreateMemento());//儲存狀態 o->setState("Off");//當遊戲掛掉 o->Show(); o->SetMemento(c->getMemento());//恢複之前儲存的備忘錄狀態 o->Show(); }
三,樣本(儲存遊戲進度)
玩遊戲的時候,通常為了可以重複玩某一關關卡,在闖關之前先儲存遊戲狀態。然後,假如沒有闖關成功,再恢複到之前的狀態重新闖關。
1)最原始的儲存遊戲進度方法
方法:建立立一個遊戲角色類,用以儲存狀態。
當需要恢複狀態的時候,讓狀態儲存類的資料恢複到遊戲角色類中
缺點:暴漏了實現細節
#include <iostream>using namespace std; class GameRole { //生命力 private: int vit; public: int getVitality() { return vit; } void setVitality(int value) { this->vit = value; } //攻擊力 private: int atk; public: int getAttack() { return atk; } void setAttack(int value) { this->atk = value; } //防禦力 private: int def; public: int getDefense() { return def; } void setDefense(int value) { this->def = value; } //狀態顯示 void StateDisplay() { cout<<"角色目前狀態:"<<endl; cout<<"體力:"<<this->vit<<endl; cout<<"攻擊力:"<<this->atk<<endl; cout<<"防禦力:"<<this->def<<endl; } //獲得初始狀態 void GetInitState() { this->vit = 100; this->atk = 100; this->def = 100; } //戰鬥 void Fight() { this->vit = 0; this->atk = 0; this->def = 0; } }; int main() { //大戰Boss前 GameRole *lixiaoyao = new GameRole(); lixiaoyao->GetInitState(); lixiaoyao->StateDisplay(); //儲存進度 GameRole *backup = new GameRole(); backup->setVitality(lixiaoyao->getVitality()); backup->setAttack(lixiaoyao->getAttack()); backup->setDefense(lixiaoyao->getDefense()); //大戰Boss時,損耗嚴重 lixiaoyao->Fight(); lixiaoyao->StateDisplay(); //恢複之前狀態 lixiaoyao->setVitality(backup->getVitality()); lixiaoyao->setAttack(backup->getAttack()); lixiaoyao->setDefense(backup->getDefense()); lixiaoyao->StateDisplay(); }
2)備忘錄模式
優點:用戶端隱藏了實現細節。
#include <iostream>using namespace std; //角色狀態儲存箱 class RoleStateMemento { private: int vit; int atk; int def; public: RoleStateMemento(int vit, int atk, int def) { this->vit = vit; this->atk = atk; this->def = def; } //生命力 int getVitality() { return vit; } void setVitality(int value) { this->vit = value; } //攻擊力 int getAttack() { return atk; } void setAttack(int value) { this->atk = value; } //防禦力 int getDefense() { return def; } void setDefense(int value) { this->def = value; } }; class GameRole { //生命力 private: int vit; public: int getVitality() { return vit; } void setVitality(int value) { this->vit = value; } //攻擊力 private: int atk; public: int getAttack() { return atk; } void setAttack(int value) { this->atk = value; } //防禦力 private: int def; public: int getDefense() { return def; } void setDefense(int value) { this->def = value; } //狀態顯示 void StateDisplay() { cout<<"角色目前狀態:"<<endl; cout<<"體力:"<<this->vit<<endl; cout<<"攻擊力:"<<this->atk<<endl; cout<<"防禦力:"<<this->def<<endl; } //儲存角色狀態 RoleStateMemento *SaveState() { return (new RoleStateMemento(vit, atk, def)); } //恢複角色狀態 void RecoveryState(RoleStateMemento *memento) { this->vit = memento->getVitality(); this->atk = memento->getAttack(); this->def = memento->getDefense(); } //獲得初始狀態 void GetInitState() { this->vit = 100; this->atk = 100; this->def = 100; } //戰鬥 void Fight() { this->vit = 0; this->atk = 0; this->def = 0; } }; //角色狀態管理者 class RoleStateCaretaker { private: RoleStateMemento *memento; public: RoleStateMemento* getMemento() { return memento; } void setMemento(RoleStateMemento *value) { this->memento = value; } }; int main() { //大戰Boss前 GameRole *lixiaoyao = new GameRole(); lixiaoyao->GetInitState(); lixiaoyao->StateDisplay(); //儲存進度 RoleStateCaretaker *stateAdmin = new RoleStateCaretaker(); stateAdmin->setMemento(lixiaoyao->SaveState()); //大戰Boss時,損耗嚴重 lixiaoyao->Fight(); lixiaoyao->StateDisplay(); //恢複之前狀態 lixiaoyao->RecoveryState(stateAdmin->getMemento()); lixiaoyao->StateDisplay(); }