備忘錄模式
備忘錄模式(Memento Pattern)保存一個對象的某個狀態,以便在適當的時候恢復對象。備忘錄模式屬於行爲型模式。
介紹
意圖:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。
主要解決:所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣可以在以後將對象恢復到原先保存的狀態。
何時使用:很多時候我們總是需要記錄一個對象的內部狀態,這樣做的目的就是爲了允許用戶取消不確定或者錯誤的操作,能夠恢復到他原先的狀態,使得他有"後悔藥"可吃。
如何解決:通過一個備忘錄類專門存儲對象狀態。
關鍵代碼:客戶不與備忘錄類耦合,與備忘錄管理類耦合。
應用實例: 1、後悔藥。 2、打遊戲時的存檔。 3、Windows 裏的 ctri + z。 4、IE 中的後退。 4、數據庫的事務管理。
優點: 1、給用戶提供了一種可以恢復狀態的機制,可以使用戶能夠比較方便地回到某個歷史的狀態。 2、實現了信息的封裝,使得用戶不需要關心狀態的保存細節。
缺點:消耗資源。如果類的成員變量過多,勢必會佔用比較大的資源,而且每一次保存都會消耗一定的內存。
使用場景: 1、需要保存/恢復數據的相關狀態場景。 2、提供一個可回滾的操作。
注意事項: 1、爲了符合迪米特原則,還要增加一個管理備忘錄的類。 2、爲了節約內存,可使用原型模式+備忘錄模式。
#include <windows.h>
#include <iostream>
using namespace std;
// 備忘錄,(需要保存的信息)
class Memento
{
public:
Memento(){}
Memento(int iLifeValue,int iAttack,int iDefense) :m_iLifeValue(iLifeValue),m_iAttack(iAttack), m_iDefense(iDefense)
{
}
// 設置生命值
void SetLifeValue(int iValue)
{
m_iLifeValue = iValue;
}
int GetLifeValue()
{
return m_iLifeValue;
}
// 設置攻擊力
void SetAttack(int iAttack)
{
m_iAttack = iAttack;
}
int GetAttack()
{
return m_iAttack;
}
// 設置防禦力
void SetDefense(int iDefense)
{
m_iDefense = iDefense;
}
// 獲取防禦力
int GetDefense()
{
return m_iDefense;
}
private:
int m_iLifeValue; // 生命值
int m_iAttack; // 攻擊力
int m_iDefense; // 防禦力
};
// 遊戲角色
class PlayerRole
{
public:
PlayerRole(int iLifeValue, int iAttack, int iDefense) :m_iLifeValue(iLifeValue), m_iAttack(iAttack), m_iDefense(iDefense)
{
}
public:
// 保存進度
Memento Save()
{
Memento mMemento;
mMemento.SetLifeValue(m_iLifeValue);
mMemento.SetAttack(m_iAttack);
mMemento.SetDefense(m_iDefense);
return mMemento;
}
// 加載進度
void Load(Memento &mMemento)
{
m_iLifeValue = mMemento.GetLifeValue();
m_iAttack = mMemento.GetAttack();
m_iDefense = mMemento.GetDefense();
}
// 玩家信息展示
void Show()
{
cout <<" 生命值: " << m_iLifeValue << endl;
cout <<" 攻擊力: " << m_iAttack << endl;
cout <<" 血量: " << m_iDefense << endl;
}
// 玩家戰敗
void PlayerDefeat()
{
m_iLifeValue = 0;
m_iAttack = 0;
m_iDefense = 0;
}
private:
int m_iLifeValue; // 生命值
int m_iAttack; // 攻擊力
int m_iDefense; // 防禦力
};
// 遊戲進度管理
class StateCareTaker
{
public:
StateCareTaker()
{
}
void Save(Memento &mMemento)
{
m_Memento = mMemento;
}
Memento Load()
{
return m_Memento;
}
private:
Memento m_Memento;
};
int main()
{
PlayerRole mPlayer(200,300,400);
mPlayer.Show();
StateCareTaker mStateTaker; // 管理類
mStateTaker.Save(mPlayer.Save());
mPlayer.PlayerDefeat();
mPlayer.Show();
mPlayer.Load(mStateTaker.Load());
mPlayer.Show();
system("pause");
return 0;
}