B: 代碼無錯未必優。
A: 問題主要在於這客戶端的調用。應爲這樣寫就把整個遊戲角色的細節暴露給了客戶端,你客戶端職責就太大了。
A: 顯然,遊戲角色的存取細節封裝起來,並且最好封裝在外部的類當中。以體現職責分離。this
在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就能夠將該對象恢復到原先保存的狀態。
B: 若是咱們不須要保存所有的信息?
A: 只是部分,那麼就應該有一個獨立的備忘錄類Memento,它只擁有須要保存的信息的屬性。spa
class Program { 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(); } } class Originator { private string state; public string State { get { return state; } set { state = value; } } public Memento CreateMemento() { return (new Memento(state)); } public void SetMemento(Memento memento) { state = memento.State; } public void Show() { Console.WriteLine("State=" + state); } } class Memento { private string state; public Memento(string state) { this.state = state; } public string State { get { return state; } } } class Caretaker { private Memento memento; public Memento Memento { get { return memento; } set { memento = value; } } }
B: 就是把保存的細節封裝在了Memento了,哪一天要更改保存的細節也不用影響客服端了。
A: Memento模式比較適合於功能比較複雜的,但須要維護或記錄屬性歷史的類,或者須要保存的屬性只是衆多屬性中的一小部分,Origniator能夠根據保存的Memento信息還原到前以狀態。
A: 若是在某個系統中使用命令模式,須要實現命令的撤銷功能,那麼命令模式可使用備忘錄模式來存儲可撤銷操做的狀態。保存在對象之外的地方,可是必須有對象本身讀取,這時,使用備忘錄能夠把複雜的對象內部信息對其餘的對象屏蔽起來,從而能夠恰當的保持封裝的邊界。
B: 當角色的狀態改變的時候,有可能這個狀態無效,這時候就可使用暫時存儲起來的備忘錄將狀態復原。code
class Program { 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(); } } class GameRole { //生命力 private int vit; public int Vitality { get { return vit; } set { vit = value; } } //攻擊力 private int atk; public int Attack { get { return atk; } set { atk = value; } } //防護力 private int def; public int Defense { get { return def; } set { def = value; } } //狀態顯示 public void StateDisplay() { Console.WriteLine("角色當前狀態:"); Console.WriteLine("體力:{0}", this.vit); Console.WriteLine("攻擊力:{0}", this.atk); Console.WriteLine("防護力:{0}", this.def); Console.WriteLine(""); } //保存角色狀態 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; } //得到初始狀態 public void GetInitState() { this.vit = 100; this.atk = 100; this.def = 100; } //戰鬥 public void Fight() { this.vit = 0; this.atk = 0; this.def = 0; } } //角色狀態存儲箱 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 Vitality { get { return vit; } set { vit = value; } } //攻擊力 public int Attack { get { return atk; } set { atk = value; } } //防護力 public int Defense { get { return def; } set { def = value; } } } //角色狀態管理者 class RoleStateCaretaker { private RoleStateMemento memento; public RoleStateMemento Memento { get { return memento; } set { memento = value; } } }
A: 若是狀態數據很大不少,那麼在資源的消耗上,備忘錄對象會很是耗內存。對象