軟件領域中的設計模式為開發人員提供了一種使用專家設計經驗的有效途徑。設計模式中運用了面向對象編程語言的重要特性:封裝、繼承、多態,真正領悟設計模式的精髓是可能一個漫長的過程,需要大量實踐經驗的積累。最近看設計模式的書,對于每個模式,用C++寫了個小例子,加深一下理解。主要參考《大話設計模式》和《設計模式:可復用面向對象軟件的基礎》兩本書。本文介紹備忘錄模式的實現。
備忘錄模式:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態。這樣以后就可將該對象恢復到原先保存的狀態[DP]。舉個簡單的例子,我們玩游戲時都會保存進度,所保存的進度以文件的形式存在。這樣下次就可以繼續玩,而不用從頭開始。這里的進度其實就是游戲的內部狀態,而這里的文件相當于是在游戲之外保存狀態。這樣,下次就可以從文件中讀入保存的進度,從而恢復到原來的狀態。這就是備忘錄模式。
給出備忘錄模式的UML圖,以保存游戲的進度為例。

Memento類定義了內部的狀態,而Caretake類是一個保存進度的管理者,GameRole類是游戲角色類。可以看到GameRole的對象依賴于Memento對象,而與Caretake對象無關。下面給出一個簡單的是實現。
~~~
//需保存的信息
class Memento
{
public:
int m_vitality; //生命值
int m_attack; //進攻值
int m_defense; //防守值
public:
Memento(int vitality, int attack, int defense):
m_vitality(vitality),m_attack(attack),m_defense(defense){}
Memento& operator=(const Memento &memento)
{
m_vitality = memento.m_vitality;
m_attack = memento.m_attack;
m_defense = memento.m_defense;
return *this;
}
};
//游戲角色
class GameRole
{
private:
int m_vitality;
int m_attack;
int m_defense;
public:
GameRole(): m_vitality(100),m_attack(100),m_defense(100) {}
Memento Save() //保存進度,只與Memento對象交互,并不牽涉到Caretake
{
Memento memento(m_vitality, m_attack, m_defense);
return memento;
}
void Load(Memento memento) //載入進度,只與Memento對象交互,并不牽涉到Caretake
{
m_vitality = memento.m_vitality;
m_attack = memento.m_attack;
m_defense = memento.m_defense;
}
void Show() { cout<<"vitality : "<< m_vitality<<", attack : "<< m_attack<<", defense : "<< m_defense<<endl; }
void Attack() { m_vitality -= 10; m_attack -= 10; m_defense -= 10; }
};
//保存的進度庫
class Caretake
{
public:
Caretake() {}
void Save(Memento menento) { m_vecMemento.push_back(menento); }
Memento Load(int state) { return m_vecMemento[state]; }
private:
vector<Memento> m_vecMemento;
};
~~~
客戶使用方式:
~~~
//測試案例
int main()
{
Caretake caretake;
GameRole role;
role.Show(); //初始值
caretake.Save(role.Save()); //保存狀態
role.Attack();
role.Show(); //進攻后
role.Load(caretake.Load(0)); //載入狀態
role.Show(); //恢復到狀態0
return 0;
}
~~~
本人享有博客文章的版權,轉載請標明出處?[http://blog.csdn.net/wuzhekai1985](http://blog.csdn.net/wuzhekai1985)