备忘录模式(Memento Pattern)

简介

备忘录模式有两个目标:

  • 储存系统关键对象的重要状态;
  • 维护关键对象的封装。

单一职责原则告诉我们,设计时不要把保持状态的工作和关键对象混在一起。这个专门掌握状态的对象,就称为备忘录。

备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用存储起来的备忘录将状态复原,当前很多软件都提供了Undo(撤销)操作功能,就使用了备忘录模式。

备忘录模式 - 图1

Originator(发起人):负责创建一个备忘录Memeto,用以记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。Originator可根据需要决定Memento储存Originator的哪些状态。

Memeto(备忘录):负责存储Originator对象的内部状态,并可防止Originator意外的其它对象访问备忘录Memeto。备忘录有两个接口,Creataker只能看到备忘录的窄接口,它只能将备忘录传递给其它对象。Originator只能看到一个窄接口,允许它访问返回到先前状态所需的所有数据。

Caretaker(管理者):负责保存好备忘录Memeto,不能对备忘录的内容进行操作或检查。

发起人(Originator)类

  1. class Originator
  2. {
  3. private string state;
  4. public string State
  5. {
  6. get {return state;}
  7. set {state = value;}
  8. }
  9. public Memnto CreateMemento()
  10. {
  11. return (new Memeto(state));
  12. }
  13. public void SetMemento(Memento memento)
  14. {
  15. state = memento.state
  16. }
  17. public void show()
  18. {
  19. Console.WriteLine("State="+ state);
  20. }
  21. }

备忘录(Memento)类

  1. class Memento
  2. {
  3. private string state;
  4. public Memento(string state)
  5. {
  6. this.state = state;
  7. }
  8. public string State
  9. {
  10. get {return state;}
  11. }
  12. }

管理者(Caretaker)类

  1. class Caretaker
  2. {
  3. private Memento memento;
  4. public Memento Memento
  5. {
  6. get {return memento;}
  7. set {memento = value;}
  8. }
  9. }

客户端程序

  1. static void Main(string[] args)
  2. {
  3. Originator o = new Originator();
  4. o.State = "On";
  5. o.show();
  6. Caretaker c = new Caretaker();
  7. c.Memento = o.CreateMemento();
  8. o.State = "Off";
  9. o.Show();
  10. o.SetMemento(c.Memento);
  11. o.Show();
  12. Console.Read();
  13. }

Memento模式比较适用于功能比较复杂的,但是需要维护或者纪录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。

如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来储存可撤销操作的状态。

当角色状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

游戏角色类

  1. class 游戏角色
  2. {
  3. ......
  4. //保存角色状态
  5. public RoleStateMemento SaveState()
  6. {
  7. return (new RoleStateMemento(vit, atk, def));
  8. }
  9. //恢复角色状态
  10. public void RecoveryState(RoleStateMemento memento)
  11. {
  12. this.vit = memento.Vitality;
  13. this.atk = memento.Attack;
  14. this.def = memento.Defense;
  15. }
  16. ......
  17. }

角色状态储存箱类

  1. class RoleStateMemento
  2. {
  3. private int vit;
  4. private int atk;
  5. private int def;
  6. public RoleStateMemento(int vit, int atk, int def)
  7. {
  8. this.vit = vit;
  9. this.atk = atk;
  10. this.def = def;
  11. }
  12. //生命力
  13. public int Vtality
  14. {
  15. get {return vit;}
  16. set {vit = value;}
  17. }
  18. //攻击力
  19. public int Attack
  20. {
  21. get {return atk;}
  22. set {vit = value;}
  23. }
  24. //防御力
  25. public int Defense
  26. {
  27. get {return def;}
  28. set {def = value;}
  29. }
  30. }

角色状态管理者

  1. class RoleStateCaretaker
  2. {
  3. private RoleStateMemeto memento;
  4. public RoleStateMemento Memento
  5. {
  6. get {return memento;}
  7. set {memento = value;}
  8. }
  9. }

客户端代码

  1. static void Main(string[] args)
  2. {
  3. //大战Boss前
  4. GameRole lixiaoyao = new GameRole();
  5. lixiaoyao.GetInitState();
  6. lixiaoyao.StateDisplay();
  7. //保存进度
  8. RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
  9. stateAdmin.memento = lixiaoyao.SaveState();
  10. //大战Boss时,损耗严重
  11. lixiaoyao.Fight();
  12. lixiaoyao.StateDisplay();
  13. //恢复之前状态
  14. lixiaoyao.RecoveryState(stateAdmin.Memento);
  15. lixiaoyao.StateDisplay();
  16. Console.Read();
  17. }