设计模式-备忘录模式

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//攻击力 private int atk; public int Attack { get { return atk; } set { atk = value; } } //防御力 private int def; public int Defense { get { return def; } set { def = value; } }
动机
有时候用户需要撤销多步操作 实现方案:在负责人类中定义一个集合来存储多个备 忘录,每个备忘录负责保存一个历史状态,在撤销时 可以对备忘录集合进行逆向遍历,回到一个指定的历 史状态,还可以对备忘录集合进行正向遍历,实现重 做(Redo)或恢复操作,即取消撤销,让对象状态得到 恢复
www.ChinaSA.info
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的实现
Java语言实现: • 将Memento类与Originator类定义在同一个包 (package)中来实现封装,使用默认访问标识符来定 义Memento类,即保证其在包内可见 • 将备忘录类作为原发器类的内部类,使得只有原发 器才可以访问备忘录中的数据,其他对象都无法使 用备忘录中的数据
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的实现
典型的负责人类代码:
namespace MementoSample { public class Caretaker { private Memento memento; internal Memento GetMemento() { return memento; } internal void SetMemento(Memento memento) { this.memento = memento; } } }
state=m.GetState();
memento
Caretaker
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的结构
备忘录模式包含以下3个角色: • Originator(原发器) • Memento(备忘录) • Caretaker(负责人)
备忘录模式的结构与实现
备忘录模式的结构
Originator - state : + RestoreMemento (Memento m) + CreateMemento () ... Memento - state : + GetState () + SetState ( state) ...
return new Memento(state);
备忘录模式的应用实例
保存游戏进度
游戏角色、生命力、攻击力、防御力 模拟战斗代码,读取游戏进度
不使用备忘录模式的代码
百度文库
www.ChinaSA.info
备忘录模式的应用实例
class GameRole { //生命力 private int vit; public int Vitality { get { return vit; } set { vit = value; } } //状态显示 public void StateDisplay() { Console.WriteLine("角色当前状态:"); Console.WriteLine("体力:{0}", this.vit); Console.WriteLine("攻击力:{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
www.ChinaSA.info
备忘录模式的应用实例
结果及分析
通过创建备忘录对象可以将象棋棋子的历史状态信息 记录下来,在“悔棋”时取出存储在备忘录中的历史 状态信息,用历史状态来覆盖当前状态,从而实现状 态的撤销
www.ChinaSA.info
实现多次撤销
www.ChinaSA.info
备忘录模式的应用实例
实例二
www.ChinaSA.info
备忘录模式的应用实例
www.ChinaSA.info
备忘录模式的应用实例
www.ChinaSA.info
备忘录模式的应用实例
www.ChinaSA.info
备忘录模式的应用实例
www.ChinaSA.info
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的实现
客户端演示代码:
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)"); Console.WriteLine(ori.GetState()); //从负责人对象中取出备忘录对象,实现撤销 ori.RestoreMemento(ct.GetMemento()); Console.WriteLine(ori.GetState()); Console.Read(); } }
(2) ChessmanMemento:象棋棋子备忘录类,充当备忘录
实例代码
www.ChinaSA.info
(3) MementoCaretaker:象棋棋子备忘录管理类,充当负责人
实例代码
(4) Program:客户端测试类
www.ChinaSA.info
实例代码
(5) 编译并运行程序,结果如下:
www.ChinaSA.info
备忘录模式概述
备忘录模式的定义
备忘录模式:在不破坏封装的前提下,捕获一个对象的内 部状态,并在该对象之外保存这个状态,这样就可以在以后 将对象恢复到原先保存的状态。 Memento Pattern: Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. 对象行为型模式
备忘录模式——软件中的“后悔药”——撤销 (Undo)
www.ChinaSA.info
备忘录模式概述
分析
通过使用备忘录模式可以让系统 恢复到某一特定的历史状态 首先保存软件系统的历史状态, 当用户需要取消错误操作并且返 回到某个历史状态时,可以取出 事先保存的历史状态来覆盖当前 状态
Design Patterns
www.ChinaSA.info
备忘录模式
10103415 唐林
www.ChinaSA.info
大纲
备忘录模式概述
备忘录模式的结构与实现 备忘录模式的应用实例 实现多次撤销 备忘录模式的优缺点与适用环境
www.ChinaSA.info
备忘录模式概述
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的实现
除了Originator类,不允许其他类来调用备忘录类 Memento的构造函数与相关方法 如果允许其他类调用SetState()等方法,将导致在备 忘录中保存的历史状态发生改变,通过撤销操作所恢 复的状态就不再是真实的历史状态,备忘录模式也就 失去了本身的意义 理想的情况是只允许生成该备忘录的原发器访问备忘 录的内部状态
www.ChinaSA.info
备忘录模式概述
备忘录模式的定义
别名为标记(Token)模式 提供了一种状态恢复的实现机制,使得用户可以方便 地回到一个特定的历史步骤 当前在很多软件所提供的撤销(Undo)操作中就使用了 备忘录模式
www.ChinaSA.info
备忘录模式的结构与实现
实现多次撤销
运行结果
www.ChinaSA.info
实现多次撤销
扩展
本实例只能实现最简单的Undo和Redo操作,并未 考虑对象状态在操作过程中出现分支的情况。如果在撤销 到某个历史状态之后,用户再修改对象状态,此后执行 Undo操作时可能会发生对象状态错误,大家可以思考其 产生原因。【注:可将对象状态的改变绘制成一张树状图 进行分析。】 在实际开发中,可以使用链表或者堆栈来处理有分支 的对象状态改变,大家可通过链表或者堆栈对上述实例进 行改进。
中国象棋软件界面示意图 为了实现“悔棋”功能,现使用备忘录模式来设计该中国象棋软件。
www.ChinaSA.info
备忘录模式的应用实例
实例类图
中国象棋棋子撤销功能结构图
实例代码
(1) Chessman:象棋棋子类,充当原发器
www.ChinaSA.info
实例代码
www.ChinaSA.info
备忘录模式的实现
典型的原发器类代码:
namespace MementoSample { www.ChinaSA.info 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) { state = m.GetState(); } public void SetState(string state) { this.state=state; } public string GetState() { return this.state; } } }
实现多次撤销
结构
改进之后的中国象棋棋子撤销功能结构图
www.ChinaSA.info
实现多次撤销
修改MementoCaretaker类
www.ChinaSA.info
实现多次撤销
客户端测试代码
www.ChinaSA.info
实现多次撤销
客户端测试代码
www.ChinaSA.info
www.ChinaSA.info
备忘录模式的结构与实现
备忘录模式的实现
典型的备忘录类代码:
namespace MementoSample { //备忘录类,默认可见性,在程序集内可见 internal class Memento { private string state; internal Memento(Originator o) { state = o.GetState(); } internal void SetState(string state) { this.state = state; } internal string GetState() { return this.state; } } }
On Off On
www.ChinaSA.info
备忘录模式的应用实例
实例一
某软件公司欲开发一款可以运行在Android平台的触摸式中国象棋软 件,由于考虑到有些用户是“菜鸟”,经常不小心走错棋;还有些用户 因为不习惯使用手指在手机屏幕上拖动棋子,常常出现操作失误,因此 该中国象棋软件要提供“悔棋”功能,用户走错棋或操作失误后可恢复 到前一个步骤。如下图所示:
}
不使用备忘录模式的代码
www.ChinaSA.info
相关文档
最新文档