设计模式-备忘录模式_第1页
设计模式-备忘录模式_第2页
设计模式-备忘录模式_第3页
设计模式-备忘录模式_第4页
设计模式-备忘录模式_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、www.ChinaSA.infoDesign Patterns备忘录模式备忘录模式10103415唐林唐林www.ChinaSA.info大纲w 备忘录模式概述w 备忘录模式的结构与实现w 备忘录模式的应用实例w 实现多次撤销w 备忘录模式的优缺点与适用环境www.ChinaSA.info备忘录模式概述w 备忘录模式软件中的“后悔药”撤销(Undo)www.ChinaSA.info备忘录模式概述w 分析通过使用备忘录模式可以通过使用备忘录模式可以让系统让系统恢复到某一特定的历史状态恢复到某一特定的历史状态首先首先保存软件系统的历史状态保存软件系统的历史状态,当用户需要取消错误操作并且返当用户需

2、要取消错误操作并且返回到某个历史状态时,可以回到某个历史状态时,可以取出取出事先保存的历史状态来覆盖当前事先保存的历史状态来覆盖当前状态状态www.ChinaSA.info备忘录模式概述w 备忘录模式的定义对象行为型对象行为型模式模式备忘录模式:备忘录模式:在不破坏封装的前提下在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后可以在以后将对象恢复到原先保存的状态将对象恢复到原先保存的状态。Memento Pattern: Without violating encapsulation, capture and externalize an objects

3、 internal state so that the object can be restored to this state later.www.ChinaSA.info备忘录模式概述w 备忘录模式的定义别名为别名为标记标记(Token)模式模式提供了一种提供了一种状态恢复状态恢复的实现机制,使得用户可以方便的实现机制,使得用户可以方便地地回到一个特定的历史步骤回到一个特定的历史步骤当前在很多软件所提供的当前在很多软件所提供的撤销撤销(Undo)操作操作中就使用了中就使用了备忘录模式备忘录模式www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的结构mementoretur

4、n new Memento(state);Originator- state : +RestoreMemento (Memento m)CreateMemento ().Memento- state : +GetState ()SetState ( state).Caretakerstate=m.GetState();www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的结构备忘录模式包含以下备忘录模式包含以下3个角色:个角色: Originator(原发器) Memento(备忘录) Caretaker(负责人)www.ChinaSA.info备忘录模式的结构与实现w 备忘录

5、模式的实现典型的原发器类代码:典型的原发器类代码:namespace MementoSample public class Originator private string state; public Originator(string state) this.state = state; / 创建一个备忘录对象创建一个备忘录对象 internal Memento CreateMemento() return new Memento(this); / 根据备忘录对象恢复原发器状态根据备忘录对象恢复原发器状态 internal void RestoreMemento(Memento m) st

6、ate = m.GetState(); public void SetState(string state) this.state=state; public string GetState() return this.state; www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的实现典型的备忘录类代码:典型的备忘录类代码:namespace MementoSample /备忘录类,默认可见性备忘录类,默认可见性,在在程序程序集内可见集内可见 internal class Memento private string state; internal Memento(Ori

7、ginator o) state = o.GetState(); internal void SetState(string state) this.state = state; internal string GetState() return this.state; www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的实现除了除了Originator类,类,不允许其他类来调用备忘录类不允许其他类来调用备忘录类Memento的构造函数与相关方法的构造函数与相关方法如果允许其他类调用如果允许其他类调用SetState()等方法,将导致在备等方法,将导致在备忘录中保存的历史状态

8、发生改变,通过撤销操作所恢忘录中保存的历史状态发生改变,通过撤销操作所恢复的状态就不再是真实的历史状态复的状态就不再是真实的历史状态,备忘录模式也就,备忘录模式也就失去了本身的意义失去了本身的意义 理想的情况是理想的情况是只允许生成该备忘录的原发器访问备忘只允许生成该备忘录的原发器访问备忘录的内部状态录的内部状态www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的实现Java语言实现:语言实现: 将Memento类与Originator类定义在同一个包(package)中来实现封装,使用默认访问标识符来定义Memento类,即保证其在包内可见 将备忘录类作为原发器类的内部类,

9、使得只有原发器才可以访问备忘录中的数据,其他对象都无法使用备忘录中的数据www.ChinaSA.info备忘录模式的结构与实现w 备忘录模式的实现典型的负责人类代码:典型的负责人类代码:namespace MementoSample public class Caretaker private Memento memento; internal Memento GetMemento() return memento; internal void SetMemento(Memento memento) this.memento = memento; www.ChinaSA.info备忘录模式的结

10、构与实现w 备忘录模式的实现客户端演示代码:客户端演示代码:class Client public static void main(String args) /创建原发器对象创建原发器对象 Originator ori = new Originator(状态状态(1); Console.WriteLine(ori.GetState(); /创建负责人对象,保存创建的备忘录对象创建负责人对象,保存创建的备忘录对象 Caretaker ct = new Caretaker(); ct.SetMemento(ori.CreateMemento(); ori.SetState(状态状态(2); Co

11、nsole.WriteLine(ori.GetState(); /从负责人对象中取出备忘录对象,实现撤销从负责人对象中取出备忘录对象,实现撤销 ori.RestoreMemento(ct.GetMemento(); Console.WriteLine(ori.GetState(); Console.Read(); OnOffOnwww.ChinaSA.info备忘录模式的应用实例w 实例一某软件公司欲开发一款可以运行在Android平台的触摸式中国象棋软件,由于考虑到有些用户是“菜鸟”,经常不小心走错棋;还有些用户因为不习惯使用手指在手机屏幕上拖动棋子,常常出现操作失误,因此该中国象棋软件要提

12、供“悔棋”功能,用户走错棋或操作失误后可恢复到前一个步骤。如下图所示: 中国象棋软件界面示意图中国象棋软件界面示意图为了实现“悔棋”功能,现使用备忘录模式来设计该中国象棋软件。www.ChinaSA.info备忘录模式的应用实例w 实例类图中国象棋棋子撤销功能结构图中国象棋棋子撤销功能结构图www.ChinaSA.infow 实例代码 (1) Chessman:象棋棋子类,充当原发器:象棋棋子类,充当原发器www.ChinaSA.infow 实例代码 (2) ChessmanMemento:象棋棋子备忘录类,充当备忘录:象棋棋子备忘录类,充当备忘录www.ChinaSA.infow 实例代码

13、(3) MementoCaretaker:象棋棋子备忘录管理类,充当负责人:象棋棋子备忘录管理类,充当负责人www.ChinaSA.infow 实例代码 (4) Program:客户端测试类:客户端测试类www.ChinaSA.infow 实例代码 (5) 编译并运行程序,结果如下:编译并运行程序,结果如下:www.ChinaSA.info备忘录模式的应用实例w 结果及分析通过创建备忘录对象可以通过创建备忘录对象可以将象棋棋子的历史状态信息将象棋棋子的历史状态信息记录下来记录下来,在,在“悔棋悔棋”时取出存储在备忘录中的历史时取出存储在备忘录中的历史状态信息,状态信息,用历史状态来覆盖当前状态

14、用历史状态来覆盖当前状态,从而实现状,从而实现状态的撤销态的撤销www.ChinaSA.info实现多次撤销w 动机有时候用户需要有时候用户需要撤销多步操作撤销多步操作实现方案:实现方案:在负责人类中在负责人类中定义一个集合定义一个集合来存储多个备来存储多个备忘录,每个备忘录负责保存一个历史状态,忘录,每个备忘录负责保存一个历史状态,在撤销时在撤销时可以对备忘录集合进行逆向遍历,回到一个指定的历可以对备忘录集合进行逆向遍历,回到一个指定的历史状态史状态,还可以,还可以对备忘录集合进行正向遍历,实现重对备忘录集合进行正向遍历,实现重做做(Redo)或恢复操作或恢复操作,即取消撤销,让对象状态得到

15、,即取消撤销,让对象状态得到恢复恢复www.ChinaSA.info实现多次撤销w 结构改进之后的中国象棋棋子撤销功能结构图改进之后的中国象棋棋子撤销功能结构图www.ChinaSA.info实现多次撤销w 修改MementoCaretaker类www.ChinaSA.info实现多次撤销w 客户端测试代码www.ChinaSA.info实现多次撤销w 客户端测试代码www.ChinaSA.info实现多次撤销w 运行结果www.ChinaSA.info实现多次撤销w 扩展 本实例只能实现最简单的本实例只能实现最简单的Undo和和Redo操作,并未操作,并未考虑对象状态在操作过程中出现分支的情

16、况。如果在撤销考虑对象状态在操作过程中出现分支的情况。如果在撤销到某个历史状态之后,用户再修改对象状态,此后执行到某个历史状态之后,用户再修改对象状态,此后执行Undo操作时可能会发生对象状态错误,大家可以思考其操作时可能会发生对象状态错误,大家可以思考其产生原因。产生原因。【注:可将对象状态的改变绘制成一张树状图注:可将对象状态的改变绘制成一张树状图进行分析。进行分析。】 在实际开发中,可以使用链表或者堆栈来处理有分支在实际开发中,可以使用链表或者堆栈来处理有分支的对象状态改变,大家可通过链表或者堆栈对上述实例进的对象状态改变,大家可通过链表或者堆栈对上述实例进行改进。行改进。www.Chi

17、naSA.info备忘录模式的应用实例w 实例二www.ChinaSA.info备忘录模式的应用实例www.ChinaSA.info备忘录模式的应用实例www.ChinaSA.info备忘录模式的应用实例www.ChinaSA.info备忘录模式的应用实例www.ChinaSA.info备忘录模式的应用实例w 保存游戏进度游戏角色、生命力、攻击力、防御力游戏角色、生命力、攻击力、防御力模拟战斗代码,读取游戏进度模拟战斗代码,读取游戏进度www.ChinaSA.info备忘录模式的应用实例 class GameRole /生命力 private int vit; public int Vital

18、ity 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(攻击

19、力:0, this.atk); Console.WriteLine(防御力:0, this.def); Console.WriteLine(); /获得初始状态 public void GetInitState() this.vit = 100; this.atk = 100; this.def = 100; /战斗 public void Fight() this.vit = 0; this.atk = 0; this.def = 0; w 不使用备忘录模式的代码www.ChinaSA.info备忘录模式的应用实例 static void Main(string args) /大战Boss前

20、 GameRole lixiaoyao = new GameRole(); lixiaoyao.GetInitState(); lixiaoyao.StateDisplay(); /保存进度 GameRole backup = new GameRole(); backup.Vitality = lixiaoyao.Vitality; backup.Attack = lixiaoyao.Attack; backup.Defense = lixiaoyao.Defense; /大战Boss时,损耗严重 lixiaoyao.Fight(); lixiaoyao.StateDisplay(); /恢复

21、之前状态 lixiaoyao.Vitality = backup.Vitality; lixiaoyao.Attack = backup.Attack; lixiaoyao.Defense = backup.Defense; lixiaoyao.StateDisplay(); Console.Read(); w 不使用备忘录模式的代码www.ChinaSA.info备忘录模式的应用实例w 使用备忘录模式的类图www.ChinaSA.info备忘录模式的应用实例w 使用备忘录模式的代码 class GameRole /保存角色状态 public RoleStateMemento SaveStat

22、e() 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 StateDisplay() Console.WriteLine(角色当前状态:); Console.WriteLine(体力:0, this.vit); Console.Wri

23、teLine(攻击力:0, this.atk); Console.WriteLine(防御力:0, this.def); Console.WriteLine(); /获得初始状态 public void GetInitState() this.vit = 100; this.atk = 100; this.def = 100; /战斗 public void Fight() this.vit = 0; this.atk = 0; this.def = 0; www.ChinaSA.info备忘录模式的应用实例w 使用备忘录模式的代码 class RoleStateMemento /角色状态存储

24、箱 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

25、 def; set def = value; www.ChinaSA.info备忘录模式的应用实例w 使用备忘录模式的代码 /角色状态管理者 class RoleStateCaretaker private RoleStateMemento memento; public void ImportState(RoleStateMemento Record) memento = Record; public RoleStateMemento ExportState() return memento; www.ChinaSA.info备忘录模式的应用实例w 使用备忘录模式的代码 static void Main(string args) /大战Boss前 GameRole lixiaoyao = new GameRole(); lixiaoyao.GetInitState(); lixiaoyao.StateDisplay(); /保存进度 RoleStateCaretaker stateAdmin = new RoleState

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论