#備忘錄模式(Memento Pattern)
##簡介
備忘錄模式有兩個目標:
* 儲存系統關鍵對象的重要狀態;
* 維護關鍵對象的封裝。
單一職責原則告訴我們,設計時不要把保持狀態的工作和關鍵對象混在一起。這個專門掌握狀態的對象,就稱為備忘錄。
備忘錄模式提供了一種狀態恢復的實現機制,使得用戶可以方便地回到一個特定的歷史步驟,當新的狀態無效或者存在問題時,可以使用存儲起來的備忘錄將狀態復原,當前很多軟件都提供了Undo(撤銷)操作功能,就使用了備忘錄模式。

Originator(發起人):負責創建一個備忘錄Memeto,用以記錄當前時刻它的內部狀態,并可以使用備忘錄恢復內部狀態。Originator可根據需要決定Memento儲存Originator的哪些狀態。
Memeto(備忘錄):負責存儲Originator對象的內部狀態,并可防止Originator意外的其它對象訪問備忘錄Memeto。備忘錄有兩個接口,Creataker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其它對象。Originator只能看到一個窄接口,允許它訪問返回到先前狀態所需的所有數據。
Caretaker(管理者):負責保存好備忘錄Memeto,不能對備忘錄的內容進行操作或檢查。
發起人(Originator)類
```
class Originator
{
private string state;
public string State
{
get {return state;}
set {state = value;}
}
public Memnto CreateMemento()
{
return (new Memeto(state));
}
public void SetMemento(Memento memento)
{
state = memento.state
}
public void show()
{
Console.WriteLine("State="+ state);
}
}
```
備忘錄(Memento)類
```
class Memento
{
private string state;
public Memento(string state)
{
this.state = state;
}
public string State
{
get {return state;}
}
}
```
管理者(Caretaker)類
```
class Caretaker
{
private Memento memento;
public Memento Memento
{
get {return memento;}
set {memento = value;}
}
}
```
客戶端程序
```
static void Main(string[] args)
{
Originator o = new Originator();
o.State = "On";
o.show();
Caretaker c = new Caretaker();
c.Memento = o.CreateMemento();
o.State = "Off";
o.Show();
o.SetMemento(c.Memento);
o.Show();
Console.Read();
}
```
Memento模式比較適用于功能比較復雜的,但是需要維護或者紀錄屬性歷史的類,或者需要保存的屬性只是眾多屬性中的一小部分時,Originator可以根據保存的Memento信息還原到前一狀態。
如果在某個系統中使用命令模式時,需要實現命令的撤銷功能,那么命令模式可以使用備忘錄模式來儲存可撤銷操作的狀態。
當角色狀態改變的時候,有可能這個狀態無效,這時候就可以使用暫時存儲起來的備忘錄將狀態復原。
游戲角色類
```
class 游戲角色
{
......
//保存角色狀態
public RoleStateMemento SaveState()
{
return (new RoleStateMemento(vit, atk, def));
}
//恢復角色狀態
public void RecoveryState(RoleStateMemento memento)
{
this.vit = memento.Vitality;
this.atk = memento.Attack;
this.def = memento.Defense;
}
......
}
```
角色狀態儲存箱類
```
class RoleStateMemento
{
private int vit;
private int atk;
private int def;
public RoleStateMemento(int vit, int atk, int def)
{
this.vit = vit;
this.atk = atk;
this.def = def;
}
//生命力
public int Vtality
{
get {return vit;}
set {vit = value;}
}
//攻擊力
public int Attack
{
get {return atk;}
set {vit = value;}
}
//防御力
public int Defense
{
get {return def;}
set {def = value;}
}
}
```
角色狀態管理者
```
class RoleStateCaretaker
{
private RoleStateMemeto memento;
public RoleStateMemento Memento
{
get {return memento;}
set {memento = value;}
}
}
```
客戶端代碼
```
static void Main(string[] args)
{
//大戰Boss前
GameRole lixiaoyao = new GameRole();
lixiaoyao.GetInitState();
lixiaoyao.StateDisplay();
//保存進度
RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
stateAdmin.memento = lixiaoyao.SaveState();
//大戰Boss時,損耗嚴重
lixiaoyao.Fight();
lixiaoyao.StateDisplay();
//恢復之前狀態
lixiaoyao.RecoveryState(stateAdmin.Memento);
lixiaoyao.StateDisplay();
Console.Read();
}
```