设计模式 - 备忘录模式

目录

[一. 前言](#一. 前言)

[二. 实现](#二. 实现)

[三. 优缺点](#三. 优缺点)


一. 前言

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

二. 实现

Originator:原始对象。

Caretaker:负责保存好备忘录。

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

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

java 复制代码
/**
 * Originator Interface
 */
public interface Calculator {
    // Create Memento
    PreviousCalculationToCareTaker backupLastCalculation();

    // setMemento
    void restorePreviousCalculation(PreviousCalculationToCareTaker memento);

    int getCalculationResult();

    void setFirstNumber(int firstNumber);

    void setSecondNumber(int secondNumber);
}
java 复制代码
/**
 * Originator Implementation
 */
public class CalculatorImp implements Calculator {
    private int firstNumber;
    private int secondNumber;

    @Override
    public PreviousCalculationToCareTaker backupLastCalculation() {
        // create a memento object used for restoring two numbers
        return new PreviousCalculationImp(firstNumber, secondNumber);
    }

    @Override
    public void restorePreviousCalculation(PreviousCalculationToCareTaker memento) {
        this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();
        this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();
    }

    @Override
    public int getCalculationResult() {
        // result is adding two numbers
        return firstNumber + secondNumber;
    }

    @Override
    public void setFirstNumber(int firstNumber) {
        this.firstNumber = firstNumber;
    }

    @Override
    public void setSecondNumber(int secondNumber) {
        this.secondNumber = secondNumber;
    }
}
java 复制代码
/**
 * 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
}
java 复制代码
/**
 * 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;
    }

    @Override
    public int getFirstNumber() {
        return firstNumber;
    }

    @Override
    public int getSecondNumber() {
        return secondNumber;
    }
}
java 复制代码
/**
 * CareTaker object
 */
public class Client {
    public static void main(String[] args) {
        // program starts
        Calculator calculator = new CalculatorImp();

        // assume user enters two numbers
        calculator.setFirstNumber(10);
        calculator.setSecondNumber(100);

        // find result
        System.out.println(calculator.getCalculationResult());

        // Store result of this calculation in case of error
        PreviousCalculationToCareTaker memento = calculator.backupLastCalculation();

        // user enters a number
        calculator.setFirstNumber(17);

        // user enters a wrong second number and calculates result
        calculator.setSecondNumber(-290);

        // calculate result
        System.out.println(calculator.getCalculationResult());

        // user hits CTRL + Z to undo last operation and see last result
        calculator.restorePreviousCalculation(memento);

        // result restored
        System.out.println(calculator.getCalculationResult());
    }
}
java 复制代码
110
-273
110

三. 优缺点

优点:

  1. 状态保存与恢复:备忘录模式可以帮助我们保存对象的状态,并在需要时恢复到之前的状态。这在某些情况下非常有用,比如撤销操作或者程序崩溃后的恢复。

  2. 封装性和隔离性:可以确保对象的状态保存在备忘录对象中,而不会暴露给其他对象。这为对象的封装性和隔离性提供了保护,使得对象的状态变化对其他对象是透明的。

缺点:

  1. 内存占用:可能引起较大的内存占用,特别是当对象的状态较多且状态改变频繁时。每个备忘录对象都需要保存一份完整的状态,如果状态较多或者备忘录对象较多,可能会消耗大量内存。

  2. 性能开销:备忘录模式涉及到创建、存储和恢复状态的操作,这些操作可能引起一定的性能开销。特别是在状态较大或者对象较复杂的情况下,备忘录模式的性能可能会受到影响。

JDK中的备忘录模式

java.io.Serializable

相关推荐
nakyoooooo3 分钟前
【设计模式】工厂模式、单例模式、观察者模式、发布订阅模式
观察者模式·单例模式·设计模式
严文文-Chris2 小时前
【设计模式-享元】
android·java·设计模式
丶白泽3 小时前
重修设计模式-设计原则
设计模式·接口隔离原则·依赖倒置原则·开闭原则
【D'accumulation】3 小时前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
仙魁XAN4 小时前
Unity 设计模式 之 创造型模式-【工厂方法模式】【抽象工厂模式】
unity·设计模式·工厂方法模式·抽象工厂模式
龙哥·三年风水14 小时前
活动系统开发之采用设计模式与非设计模式的区别-后台功能总结
设计模式·php·tinkphp6
一头老羊15 小时前
前端常用的设计模式
设计模式
严文文-Chris15 小时前
【设计模式-组合】
设计模式
kimloner16 小时前
工厂模式(二):工厂方法模式
java·设计模式·工厂方法模式
丶白泽19 小时前
重修设计模式-结构型-桥接模式
java·设计模式·桥接模式