备忘录模式

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

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

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

备忘录模式UML

UML类图

Caretaker类是指用于保存(createMemento())和还原(restore(memento))发起方内部状态的Originator类。 发起方类实现 (1)createMemento(),通过创建和返回存储发起方当前内部状态的memento对象 (2)通过从传入的memento对象还原状态来还原(memento)。

UML时序图

(1)保存发起人的内部状态:Caretaker对Originator调用createMemento(),创建memento对象,保存其当前内部状态(setState()),并将memento返回给Caretaker。

(2)恢复发起人的内部状态:Caretaker对Originator调用restore(memento),并指定存储应恢复状态的memento对象。发起者从memento获取状态(getState())以设置其自己的状态。

备忘录模式角色结构

(1) 备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。

(2) 备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。

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

干货示例

public class Caretaker {

​ public static void main(String[] args) {

​ List savedStates = new ArrayList();

​ Originator originator = new Originator();

​ originator.set("State1");

​ originator.set("State2");

​ savedStates.add(originator.saveToMemento());

​ originator.set("State3");

​ savedStates.add(originator.saveToMemento());

​ originator.set("State4");

​ originator.restoreFromMemento(savedStates.get(1));

​ }

}

@Slf4j

public class Originator {

​ private String state;

​ //状态更改

​ public void set(String state) {

​ this.state = state;

​ log.info("Originator: Setting state to {}", state);

​ }

​ //将状态保存到备忘录里

​ public Memento saveToMemento() {

​ log.info("Originator: Saving to Memento.");

​ return new Memento(this.state);

​ }

​ //从备忘录里取出状态并回滚

​ public void restoreFromMemento(Memento memento) {

​ this.state = memento.getState();

​ log.info("Originator: State after restoring from Memento: {}", state);

​ }

}

@Data

@AllArgsConstructor

public class Memento {

​ //状态维护

​ private String state;

}

复制代码

示例结果

从上述代码中看的出,随着状态变更,用List维护发起者的状态列表,从备忘录中取出状态以便回退状态。

java中的使用

生成对象状态的一个快照,以便对象可以恢复原始状态而不用暴露自身的内容。Date对象通过自身内部的一个long值来实现备忘录模式。

java.util.Date

java.io.Serializable

总结

优点

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

缺点

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

使用场景

1、需要保存/恢复数据的相关状态场景。 2、提供一个可回滚的操作。

注意事项

1、为了符合迪米特原则,还要增加一个管理备忘录的类。 2、为了节约内存,可使用原型模式+备忘录模式。

参考

欢迎关注

java备忘录模式 类图,折腾Java设计模式之备忘录模式相关推荐

  1. java备忘录模式 类图,Android编程设计模式之备忘录模式详解

    本文实例讲述了Android编程设计模式之备忘录模式.分享给大家供大家参考,具体如下: 一.介绍 备忘录模式是一种行为模式,该模式用于保存对象当前状态,并且在之后可以再次恢复到此状态,这有点像我们平时 ...

  2. java备忘录模式 类图,【java设计模式】备忘录模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述备忘录(Memento)模式的: 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式. 备忘录 ...

  3. UML类图、JAVA DesignMode 设计模式、设计原则

    全文2.6W余字,读完需要20分钟,介绍23种设计模式,每个模式都有案例与真实使用场景,能够帮助初学者快速了解设计模式,建立起对代码中设计模式的初步理解,要明确:设计模式只是帮助我们更好的设计代码架构 ...

  4. java 外观模式类图_Java 设计模式——外观模式

    概述 今天要说的外观模式是一个相对简单的设计模式,而且在日常的开发中,可能你也会时常使用它,只是你可能并未想过这是一个设计模式.本文会从一些实例着手,来对本文要说明的外观模式进行尽可能全面的讲解.希望 ...

  5. UML与Java-- UML类图于Java的基本实现

    类图是最常用的UML图,他可以清楚地表示程序中类的基本结构,类与类之间的结构关系,掌握UML类图对于了解系统的总体结构和设计模式有着重大的作用.下面我会介绍类图的基本知识以及类图在Java中的基本实现 ...

  6. 如何在类图中标注设计模式(二)

    接文章<如何在类图中标注设计模式(一)>. 本文姗姗来迟,见谅!        5.  基于标记的模式标注 美国德克萨斯大学达拉斯分校的Jing Dong等人提出了一种基于标记的模式标注方 ...

  7. java对接支付宝微信银联_经典设计模式之策略模式【如何重构聚合支付平台,对接【支付宝,微信,银联支付】】(示例代码)...

    写在前面:设计模式源于生活,而又高于生活! 为什么要使用设计模式重构代码 使用设计模式可以重构整体架构代码.提高代码复用性.扩展性.减少代码冗余问题. Java高级工程师装逼的技能! 什么是策略模式 ...

  8. java 抽象工厂 类图_spring学习中常用到的工厂,抽象工厂学习 | 学步园

    工厂模式有简单工厂模式,工厂方法模式和抽象工厂模式几种形态.其中简单工厂模式和工厂方法模式已经在前面作过介绍.在这里,我们来介绍抽象工厂模式. 抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的 ...

  9. java策略模式详解_Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式 ...

最新文章

  1. 【ES6】ES6编程规范 编程风格
  2. C十三:strcmp函数,比价字符串
  3. gis怎么通过水库划分子流域_到底是谁在革GIS的命?
  4. 网页如何有效调用exe
  5. 深入了解Mybatis架构设计
  6. Navicat工具里的empty table和truncate table的区别
  7. 参数化的JUnit测试
  8. 内蒙古工业大学计算机科学与技术,计算机科学与技术的应用领域简述论文内蒙古工业大学.doc...
  9. 基础练习 高精度加法(蓝桥杯 java)
  10. oracle中between
  11. win10安装python的xlrd_win10安装python的xlrd
  12. 苹果修复 Gatekeeper 绕过漏洞
  13. ELK + Filebeat日志分析系统安装
  14. c语言社交网络,图论在社交网络中的应用研究
  15. c语言自学文档,自学c语言(全套资料)
  16. 怎样在Edge浏览器中开启IE兼容模式
  17. 打印机驱动无法安装到计算机是,电脑打印机无法安装驱动的解决方法
  18. 记录新人tp5微信扫码支付
  19. 笨方法学python 42课笔记:物以类聚
  20. Five nines

热门文章

  1. 【Android Camera】之花落知多少
  2. web开发-css1
  3. LAMMPS回到未来计划
  4. 【Reference Reading】评估多模态影像(CT, MRI和PET)在phantom和头颈部癌症患者的配准程序:准确性,重现性和一致性
  5. 解决重启电脑后WSL/WSL2虚拟机IP地址变换的问题(非标题党)
  6. android(安卓)悠悠导航v2.3.27.1,悠悠导航app
  7. viewpager2异常: java.lang.IllegalStateException: Fragment no longer exists for key f#1: unique id 8052
  8. Apache strtus2深入精讲-王磊-专题视频课程
  9. T1103陶陶摘苹果(信息学一本通C++)
  10. 《Windows程序设计》读书笔二十 多任务和多线程