设计模式学习笔记--备忘录模式(详细笔记)

1. 概述

使用背景:

菜鸟教程

  • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
  • 所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
  • 很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。

定义:

《大话设计模式》

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

**类型:**行为型

结构:

《大话设计模式》

image-20211215102431720

《深入设计模式》

image-20211215113445086

适用场景:

菜鸟教程

  • 1、需要保存/恢复数据的相关状态场景。

  • 2、提供一个可回滚的操作。

  • 当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。

    备忘录模式允许你复制对象中的全部状态 (包括私有成员变量), 并将其独立于对象进行保存。 尽管大部分人因为 “撤销” 这个用例才记得该模式, 但其实它在处理事务 (比如需要在出现错误时回滚一个操作) 的过程中也必不可少。

  • 当直接访问对象的成员变量、 获取器或设置器将导致封装被突破时, 可以使用该模式。

    备忘录让对象自行负责创建其状态的快照。 任何其他对象都不能读取快照, 这有效地保障了数据的安全性。

实现方式:

  1. 确定担任原发器角色的类。 重要的是明确程序使用的一个原发器中心对象, 还是多个较小的对象。

  2. 创建备忘录类。 逐一声明对应每个原发器成员变量的备忘录成员变量。

  3. 将备忘录类设为不可变。 备忘录只能通过构造函数一次性接收数据。 该类中不能包含设置器。

  4. 如果你所使用的编程语言支持嵌套类, 则可将备忘录嵌套在原发器中; 如果不支持, 那么你可从备忘录类中抽取一个空接口, 然后让其他所有对象通过接口来引用备忘录。 你可在该接口中添加一些元数据操作, 但不能暴露原发器的状态。

  5. 在原发器中添加一个创建备忘录的方法。 原发器必须通过备忘录构造函数的一个或多个实际参数来将自身状态传递给备忘录。

    该方法返回结果的类型必须是你在上一步中抽取的接口 (如果你已经抽取了)。 实际上,创建备忘录的方法必须直接与备忘录类进行交互。

  6. 在原发器类中添加一个用于恢复自身状态的方法。 该方法接受备忘录对象作为参数。 如果你在之前的步骤中抽取了接口, 那么可将接口作为参数的类型。 在这种情况下, 你需要将输入对象强制转换为备忘录, 因为原发器需要拥有对该对象的完全访问权限。

  7. 无论负责人是命令对象、 历史记录或其他完全不同的东西, 它都必须要知道何时向原发器请求新的备忘录、 如何存储备忘录以及何时使用特定备忘录来对原发器进行恢复。

  8. 负责人与原发器之间的连接可以移动到备忘录类中。 在本例中, 每个备忘录都必须与创建自己的原发器相连接。 恢复方法也可以移动到备忘录类中, 但只有当备忘录类嵌套在原发器中, 或者原发器类提供了足够多的设置器并可对其状态进行重写时, 这种方式才能实现。

优点:

菜鸟教程

  • 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
  • 2、实现了信息的封装,使得用户不需要关心状态的保存细节。

《深入设计模式》

  • 你可以在不破坏对象封装情况的前提下创建对象状态快照。
  • 你可以通过让负责人维护原发器状态历史记录来简化原发器代码

缺点:

菜鸟教程

  • 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

《深入设计模式》

  • 如果客户端过于频繁地创建备忘录, 程序将消耗大量内存。
  • 负责人必须完整跟踪原发器的生命周期,这样才能销毁弃用的备忘录。
  • 绝大部分动态编程语言 (例如 PHP、Python 和 JavaScript) 不能确保备忘录中的状态不被修改。

与其他设计模式的联系:

菜鸟教程

  • 为了节约内存,可使用原型模式+备忘录模式。

《深入设计模式》

  • 你可以同时使用命令模式和备忘录模式来实现 “撤销”。 在这种情况下, 命令用于对目标对象执行各种不同的操作, 备忘录用来保存一条命令执行前该对象的状态。

  • 你可以同时使用备忘录和迭代器模式来获取当前迭代器的状态, 并且在需要的时候进行回滚。

  • 有时候原型模式可以作为备忘录的一个简化版本, 其条件是你需要在历史记录中存储的对象的状态比较简单, 不需要链接其他外部资源, 或者链接可以方便地重建。

《图解设计模式》

  • Command模式
    在使用Command模式处理命令时,可以使用Memento模式实现撤销功能。

  • Protype模式
    在 Memento模式中,为了能够实现快照和撤销功能,保存了对象当前的状态。保存的信息只是在恢复状态时所需要的那部分信息。
    而在 Protype模式中,会生成一个与当前实例完全相同的另外一个实例。这两个实例的内容完全一样。

  • State模式
    在 Memento模式中,是用“实例”表示状态。而在State模式中,则是用“类”表示状态。


2. 使用实例

菜鸟教程

1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctrl + z。 4、IE 中的后退。 5、数据库的事务管理。

《深入设计模式》

下面是核心 Java 程序库中该模式的一些示例:

引流2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值