• 设计模式 - 备忘录模式


    目录

    一. 前言

    二. 实现

    三. 优缺点


    一. 前言

        备忘录模式又称快照模式,是一种行为型设计模式。它可以在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要的时候恢复到原先保存的状态。在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。

    二. 实现

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

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

    1. /**
    2. * Originator Interface
    3. */
    4. public interface Calculator {
    5. // Create Memento
    6. PreviousCalculationToCareTaker backupLastCalculation();
    7. // setMemento
    8. void restorePreviousCalculation(PreviousCalculationToCareTaker memento);
    9. int getCalculationResult();
    10. void setFirstNumber(int firstNumber);
    11. void setSecondNumber(int secondNumber);
    12. }
    1. /**
    2. * Originator Implementation
    3. */
    4. public class CalculatorImp implements Calculator {
    5. private int firstNumber;
    6. private int secondNumber;
    7. @Override
    8. public PreviousCalculationToCareTaker backupLastCalculation() {
    9. // create a memento object used for restoring two numbers
    10. return new PreviousCalculationImp(firstNumber, secondNumber);
    11. }
    12. @Override
    13. public void restorePreviousCalculation(PreviousCalculationToCareTaker memento) {
    14. this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();
    15. this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();
    16. }
    17. @Override
    18. public int getCalculationResult() {
    19. // result is adding two numbers
    20. return firstNumber + secondNumber;
    21. }
    22. @Override
    23. public void setFirstNumber(int firstNumber) {
    24. this.firstNumber = firstNumber;
    25. }
    26. @Override
    27. public void setSecondNumber(int secondNumber) {
    28. this.secondNumber = secondNumber;
    29. }
    30. }
    1. /**
    2. * Memento Interface to Originator
    3. *
    4. * This interface allows the originator to restore its state
    5. */
    6. public interface PreviousCalculationToOriginator {
    7. int getFirstNumber();
    8. int getSecondNumber();
    9. }
    10. /**
    11. * Memento interface to CalculatorOperator (Caretaker)
    12. */
    13. public interface PreviousCalculationToCareTaker {
    14. // no operations permitted for the caretaker
    15. }
    1. /**
    2. * Memento Object Implementation
    3. *

    4. * Note that this object implements both interfaces to Originator and CareTaker
    5. */
    6. public class PreviousCalculationImp implements PreviousCalculationToCareTaker,
    7. PreviousCalculationToOriginator {
    8. private int firstNumber;
    9. private int secondNumber;
    10. public PreviousCalculationImp(int firstNumber, int secondNumber) {
    11. this.firstNumber = firstNumber;
    12. this.secondNumber = secondNumber;
    13. }
    14. @Override
    15. public int getFirstNumber() {
    16. return firstNumber;
    17. }
    18. @Override
    19. public int getSecondNumber() {
    20. return secondNumber;
    21. }
    22. }
    1. /**
    2. * CareTaker object
    3. */
    4. public class Client {
    5. public static void main(String[] args) {
    6. // program starts
    7. Calculator calculator = new CalculatorImp();
    8. // assume user enters two numbers
    9. calculator.setFirstNumber(10);
    10. calculator.setSecondNumber(100);
    11. // find result
    12. System.out.println(calculator.getCalculationResult());
    13. // Store result of this calculation in case of error
    14. PreviousCalculationToCareTaker memento = calculator.backupLastCalculation();
    15. // user enters a number
    16. calculator.setFirstNumber(17);
    17. // user enters a wrong second number and calculates result
    18. calculator.setSecondNumber(-290);
    19. // calculate result
    20. System.out.println(calculator.getCalculationResult());
    21. // user hits CTRL + Z to undo last operation and see last result
    22. calculator.restorePreviousCalculation(memento);
    23. // result restored
    24. System.out.println(calculator.getCalculationResult());
    25. }
    26. }
    1. 110
    2. -273
    3. 110

    三. 优缺点

    优点:
    1. 状态保存与恢复:备忘录模式可以帮助我们保存对象的状态,并在需要时恢复到之前的状态。这在某些情况下非常有用,比如撤销操作或者程序崩溃后的恢复。
    2. 封装性和隔离性:可以确保对象的状态保存在备忘录对象中,而不会暴露给其他对象。这为对象的封装性和隔离性提供了保护,使得对象的状态变化对其他对象是透明的。
    缺点:
    1. 内存占用:可能引起较大的内存占用,特别是当对象的状态较多且状态改变频繁时。每个备忘录对象都需要保存一份完整的状态,如果状态较多或者备忘录对象较多,可能会消耗大量内存。
    2. 性能开销:备忘录模式涉及到创建、存储和恢复状态的操作,这些操作可能引起一定的性能开销。特别是在状态较大或者对象较复杂的情况下,备忘录模式的性能可能会受到影响。

    JDK中的备忘录模式
    java.io.Serializable

  • 相关阅读:
    2022年R1快开门式压力容器操作考试模拟100题及答案
    迭代器并不全是指针,list的迭代器与vector和string的有什么不一样,让博主告诉你其底层原理!
    lodash学习笔记
    Pandas 学习
    Visual Studio Code官网下载、vscode下载很慢、vscode下载不了 解决方案
    设计模式-代理模式
    第144篇:阿里低开项目 init方法
    Docker Desktop for Windows 安装过程整理
    8.15 Day41---Linux文件系统命令
    LC1713. 得到子序列的最少操作次数(java - 动态规划)
  • 原文地址:https://blog.csdn.net/mrluo735/article/details/133746695