索引

别名

  • Token

意图

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.

结构

参与者

Memento

  • Memento 存储 Originator 对象的内部状态。Originator 根据需要决定 Memento 存储那些内部状态。
  • 防止 Originator 以外的其他对象访问 Memento。Memento 可实现两个接口,Caretaker 只能看到 Memento 的窄接口,Originator 可以看到宽接口。

Originator

  • Originator 创建一个 Memento,用以记录当前时刻的内部状态。
  • 使用 Memento 恢复内部状态。

Caretaker

  • 负责保存 Memento。
  • 不能对 Memento 的内容进行操作和检查。

适用性

在以下情况下可以使用 Memento 模式:

  • 必须保存一个对象在某一个时刻的状态,这样以后需要时它才能恢复到先前的状态。
  • 如果一个用接口来让其他对象直接得到的这些状态,将会暴露对象的实现细节并破坏对象的封装性。

效果

  • 保持封装边界。
  • 简化了 Originator。
  • 定义窄接口和宽接口。
  • 使用和维护 Memento 的潜在代价。

相关模式

  • 可以使用 Memento 存储 Command 的内部状态,以支持撤销操作。
  • Memento 可以使用 Iterator 进行迭代。

实现

Caretaker 向 Originator 请求一个 Memento,保留一段时间后,将其送回 Originator。

实现方式(一):Memento 模式结构样式代码。

Memento 有两个接口:一个为 Originator 所使用的宽接口,一个为其他对象所使用的窄接口。

  1. namespace MementoPattern.Implementation1
  2. {
  3. public class Memento
  4. {
  5. private readonly string _state;
  6.  
  7. public Memento(string state)
  8. {
  9. _state = state;
  10. }
  11.  
  12. public string GetState()
  13. {
  14. return _state;
  15. }
  16. }
  17.  
  18. public class Originator
  19. {
  20. public string State { get; set; }
  21.  
  22. public Memento CreateMemento()
  23. {
  24. return (new Memento(State));
  25. }
  26.  
  27. public void SetMemento(Memento memento)
  28. {
  29. State = memento.GetState();
  30. }
  31. }
  32.  
  33. public class Caretaker
  34. {
  35. public Memento Memento { get; set; }
  36. }
  37.  
  38. public class Client
  39. {
  40. public void TestCase1()
  41. {
  42. var originator = new Originator { State = "State A" };
  43. Console.WriteLine(originator.State);
  44.  
  45. var memento = originator.CreateMemento();
  46. var caretaker = new Caretaker { Memento = memento };
  47.  
  48. originator.State = "State B";
  49. Console.WriteLine(originator.State);
  50.  
  51. originator.SetMemento(caretaker.Memento);
  52. Console.WriteLine(originator.State);
  53. }
  54. }
  55. }

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Memento(备忘录)的更多相关文章

  1. 设计模式20:Memento 备忘录模式(行为型模式)

    Memento 备忘录模式(行为型模式) 对象状态的回溯 对象状态的变化无端,如何回溯.恢复对象在某个点的状态? 动机(Motivation) 在软件构建过程中,某些对象的状态在转换过程中,可能由于某 ...

  2. 23种设计模式 - 状态变化(Memento备忘录 - State)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 状态变化 在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的 ...

  3. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  4. 十八、Memento 备忘录设计模式

    原理: 代码清单: Memento public class Memento { int mondey; ArrayList fruits; Memento(int mondey){ this.mon ...

  5. 设计模式(18)--Memento(备忘录模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式. ...

  6. 设计模式之美:Iterator(迭代器)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Iterator 模式结构样式代码. 实现方式(二):实现 IEnumerable 中序遍历二叉树. 实现方式(三):实现 Bi ...

  7. 设计模式之美:Command(命令)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):直接注入 Receiver 对象,Command 决定调用哪个方法. 实现方式(二):注入 Receiver 的指定方法, ...

  8. Head First 设计模式系列之二----备忘录模式(java版)

    申明:这几天无意中关注到备忘录模式,比较陌生回家一番参考书,只在附录里记录了该模式.后来在园子里有发现了有专门写设计模式的博客,并且写的也得牛逼.附上链接 http://www.cnblogs.com ...

  9. 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

    面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...

随机推荐

  1. [Arduino] Arduino猪头笔记

    1. 步进电机驱动 今天才发现....原来在不同的步进电机驱动模块里面,循环时钟是不一样的.... 步进电机驱动模块以及电路配置: 驱动代码的主要部分: int sp_param = 16383; d ...

  2. XE3随笔15:使用 IXMLHTTPRequest 简单获取网页源代码

    unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, For ...

  3. $POST 、$HTTP_RAW_POST_DATA、php://input三者之间的区别

    $POST .$HTTP_RAW_POST_DATA.php://input三者之间的区别 访问原始 POST 数据的更好方法是 php://input或者$HTTP_RAW_POST_DATA.$H ...

  4. tmp

    Hello 大家好,这次给大家带来的是Gear VR4代,首先我得感谢下我们的虎友Hide兄弟友情提供Gear给我们测评,感谢 感谢.之前我录的前哨战也说过,这次Gear VR 4代较3代变化并不是很 ...

  5. SQL server 动态行转列

    用聚合函数配合CASE语句实现行转列功能: 现在分享一下具体实现代码: 转换前效果: PlanName PlanType PlanLimit 计划1 计划类型1 RMB 1,000,000 计划1 计 ...

  6. shell学习--grep2

    grep相关的练习,解释下面grep表达式的含义: grep '\<Tom\>' file 打印file中包含单词 Tom的行 grep 'Tome Savage' file 打印file ...

  7. PHP 实现单一入口 apache配置

    在apache的httpd.conf加入,需要把LoadModule rewrite_module modules/mod_rewrite.so前面的“#”去掉 DocumentRoot / < ...

  8. NABCD

    1) N (Need 需求) 随着科学技术的进步和计算机行业的迅速发展,人们的工作效率得到大大提高.计算机信息处理系统的引进已彻底改变了许多系统的经营管理. 图书管理系统是学校管理机制中的重要组成部分 ...

  9. lua 位运算

    bit = {data32={}} , do bit.data32[i] = ^(-i) end function bit:d2b( arg ) local num = tonumber( arg ) ...

  10. mac OS X 配置Python+Web.py+MySQLdb环境

    MAC默认支持Python 2.7所以不用安装. 1.安装pip sudo easy_install pip 2.安装Web.py sudo pip install Web.py 3.安装MySQLd ...