1. 应用场景

备忘录模式经常可以遇到,譬如下面这些场景:

  • 浏览器回退:浏览器一般有浏览记录,当我们在一个网页上点击几次链接之后,可在左上角点击左箭头回退到上一次的页面,然后也可以点击右箭头重新回到当前页面
  • 数据库备份与还原:一般的数据库都支持备份与还原操作,备份即将当前已有的数据或者记录保留,还原即将已经保留的数据恢复到对应的表中
  • 编辑器撤销与重做:在编辑器上编辑文字,写错时可以按快捷键 Ctrl + z 撤销,撤销后可以按 Ctrl + y 重做
  • 虚拟机生成快照与恢复:虚拟机可以生成一个快照,当虚拟机发生错误时可以恢复到快照的样子
  • Git版本管理:Git是最常见的版本管理软件,每提交一个新版本,实际上Git就会把它们自动串成一条时间线,每个版本都有一个版本号,使用 git reset --hard 版本号 即可回到指定的版本,让代码时空穿梭回到过去某个历史时刻
  • 棋牌游戏悔棋:在棋牌游戏中,有时下快了可以悔棋,回退到上一步重新下

2. 概念

在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。它是一种对象行为型模式,其别名为Token。

3. Class Diagram

  • Originator:原始对象
  • Caretaker:负责保存好备忘录
  • Menento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给
  • Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。

4. Implementation

以下实现了一个简单计算器程序,可以输入两个值,然后计算这两个值的和。备忘录模式允许将这两个值存储起来,然后在某个时刻用存储的状态进行恢复。

/*** Originator Interface*/
public interface Calculator {// Create MementoPreviousCalculationToCareTaker backupLastCalculation();// setMementovoid restorePreviousCalculation(PreviousCalculationToCareTaker memento);int getCalculationResult();void setFirstNumber(int firstNumber);void setSecondNumber(int secondNumber);
}
/*** Originator Implementation*/
public class CalculatorImp implements Calculator {private int firstNumber;private int secondNumber;@Overridepublic PreviousCalculationToCareTaker backupLastCalculation() {// create a memento object used for restoring two numbersreturn new PreviousCalculationImp(firstNumber, secondNumber);}@Overridepublic void restorePreviousCalculation(PreviousCalculationToCareTaker memento) {this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();}@Overridepublic int getCalculationResult() {// result is adding two numbersreturn firstNumber + secondNumber;}@Overridepublic void setFirstNumber(int firstNumber) {this.firstNumber = firstNumber;}@Overridepublic void setSecondNumber(int secondNumber) {this.secondNumber = secondNumber;}
}
/*** Memento Interface to Originator** This interface allows the originator to restore its state*/
public interface PreviousCalculationToOriginator {int getFirstNumber();int getSecondNumber();
}
/***  Memento interface to CalculatorOperator (Caretaker)*/
public interface PreviousCalculationToCareTaker {// no operations permitted for the caretaker
}
/*** Memento Object Implementation* <p>* Note that this object implements both interfaces to Originator and CareTaker*/
public class PreviousCalculationImp implements PreviousCalculationToCareTaker,PreviousCalculationToOriginator {private int firstNumber;private int secondNumber;public PreviousCalculationImp(int firstNumber, int secondNumber) {this.firstNumber = firstNumber;this.secondNumber = secondNumber;}@Overridepublic int getFirstNumber() {return firstNumber;}@Overridepublic int getSecondNumber() {return secondNumber;}
}
/*** CareTaker object*/
public class Client {public static void main(String[] args) {// program startsCalculator calculator = new CalculatorImp();// assume user enters two numberscalculator.setFirstNumber(10);calculator.setSecondNumber(100);// find resultSystem.out.println(calculator.getCalculationResult());// Store result of this calculation in case of errorPreviousCalculationToCareTaker memento = calculator.backupLastCalculation();// user enters a numbercalculator.setFirstNumber(17);// user enters a wrong second number and calculates resultcalculator.setSecondNumber(-290);// calculate resultSystem.out.println(calculator.getCalculationResult());// user hits CTRL + Z to undo last operation and see last resultcalculator.restorePreviousCalculation(memento);// result restoredSystem.out.println(calculator.getCalculationResult());}
}
运行结果:
110
-273
110

5. 优点和缺点

5.1 优点

  • 将被存储的状态放在外面,不要和关键对象混在一起,这样可以帮助维护内聚。
  • 保持关键对象的数据封装
  • 提供了容易实现的恢复能力

5.2 用途和缺点

  • 备忘录用于存储状态。
  • 使用备忘录的缺点:存储和恢复的过程可能相对耗时。
  • 在Java系统中,其实可以考虑用序列化(serializaiton)机制存储系统的状态。

6. JDK

  • java.io.Serializable

Java设计模式(二十一):备忘录设计模式相关推荐

  1. Java实现二十三种设计模式(五)—— 十一种行为型模式 (中)——解释器模式、迭代器模式、中介者模式、备忘录模式

    Java实现二十三种设计模式(五)-- 十一种行为型模式 (中)--解释器模式.迭代器模式.中介者模式.备忘录模式 一.解释器模式 我国 IT 界历来有一个汉语编程梦,虽然各方对于汉语编程争论不休,甚 ...

  2. Java的二十三种设计模式(单例模式、工厂方法模式、抽象工厂模式)

    从这一块开始,我们详细介绍Java中23种设计模式的概念,应用场景等情况,并结合他们的特点及设计模式的原则进行分析. 创建型模式(5种):用于描述"怎样创建对象",它的主要特点是& ...

  3. java计数器策略模式_java设计模式(二十一)--策略模式

    对于策略模式,我在很多面试题上看到过考察这一类的问题,这种模式也的确比较好用. 我感觉这种模式就是将不同实现的方法放到一个接口中,然后通过实现这个接口来实现不同的运行结果,这种模式有三部分构成: 策略 ...

  4. Java的二十三种设计模式

    设计模式介绍及Java描述 概述 设计模式是针对某一类问题的最优解决方案,是从许多优秀的软件系统中总结出的. Java中设计模式(java design patterns)通常有23种. 模式可以分成 ...

  5. Java设计模式(二):观察者设计模式

    1. 应用场景 某个实例的变化将影响其他多个对象. 观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们. 2.概念 定义对象之间的一 ...

  6. Java的二十三种设计模式(原型模式(Prototype))

    原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对象的复制,进行讲解.在Java中 ...

  7. Java的二十三种设计模式(适配器模式(Adapter)、对象的适配器模式)

    适配器模式(Adapter) 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式 ...

  8. Java的二十三种设计模式(建造者模式(Builder))

    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到 ...

  9. 设计模式(二)__装饰设计模式

    今天呢,来给大家介绍一下装饰设计模式,java中IO就使用到了这个模式. 装饰设计模式,顾名思义,就是对一个功能进行装饰,就跟女人化妆一样,人还是本人,但是化了妆就变得比原来更漂亮了. 需求:当你有个 ...

最新文章

  1. 《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(四)图像的矩
  2. quake3使用指南(转载)
  3. ThreadLocal实践
  4. mysql导入100000000需要多久_MYSQL批量插入千万级数据只需百秒
  5. 百度编辑器 UEditor setContent()
  6. 【3分钟掌握】什么是DNS解析
  7. 微信支付配置参数:支付授权目录、回调支付URL
  8. C memset 踩坑
  9. 2022年中国即时配送行业趋势研究报告
  10. 银行数据部门如何管理跟使用数据?来围观星球中老师的答案
  11. Codeforces Round #503 (by SIS, Div. 2) C. Elections
  12. LTE学习笔记:LTE总体架构
  13. PetaLinux 添加启动后自动执行脚本
  14. win7计算机摄像头怎么打开,win7的摄像头在哪里打开 怎么打开win7摄像头
  15. 页面中插入视频的方法---video/embed/iframe总结
  16. 复旦计算机可以跨专业吗,I直达录取现场I2020,还能跨考计算机吗?
  17. 漂亮的壁纸,这些网站就足够了。
  18. 二叉树的层序遍历-Java
  19. leetcode 5.最长回文子串
  20. 问题集锦:SwitchResX自定义分辨率可能遇到的问题以及解决办法

热门文章

  1. 【转】关于Ubuntu的sources.list 的总结
  2. python- is和id
  3. leetcode 105. 从前序与中序遍历序列构造二叉树
  4. Leetcode 141.环形链表
  5. 96.总线里的异步通信
  6. C#语言编程之抽象类与接口的比较
  7. Xshell 连接报错解决:WARNING! The remote SSH server rejected X11 forwarding request.
  8. 软件和硬件的关系以及软件调动硬件的工作原理
  9. 087_改变html
  10. rust高级矿场_高级 Rust 所有权管理