Skip to content

备忘录模式(Memento pattern): 当你需要让对象返回之前的状态时(例如, 你的用户请求"撤销"), 你使用备忘录模式。@anarkh

  • 行为型 - 备忘录(Memento)
  • 意图
  • 类图
  • 实现
  • JDK

意图

在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。

类图

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

实现

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

实现参考: Memento Pattern - Calculator Example - Java Sourcecode在新窗口打开

java
public interface Calculator {

    
    PreviousCalculationToCareTaker backupLastCalculation();

    
    void restorePreviousCalculation(PreviousCalculationToCareTaker memento);

    int getCalculationResult();

    void setFirstNumber(int firstNumber);

    void setSecondNumber(int secondNumber);
}
java
public class CalculatorImp implements Calculator {

    private int firstNumber;
    private int secondNumber;

    @Override
    public PreviousCalculationToCareTaker backupLastCalculation() {
        
        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() {
        
        return firstNumber + secondNumber;
    }

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

    @Override
    public void setSecondNumber(int secondNumber) {
        this.secondNumber = secondNumber;
    }
}
java
public interface PreviousCalculationToOriginator {
    int getFirstNumber();
    int getSecondNumber();
}
java
public interface PreviousCalculationToCareTaker {
    
}
java
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
public class Client {

    public static void main(String[] args) {
        
        Calculator calculator = new CalculatorImp();

        
        calculator.setFirstNumber(10);
        calculator.setSecondNumber(100);

        
        System.out.println(calculator.getCalculationResult());

        
        PreviousCalculationToCareTaker memento = calculator.backupLastCalculation();

        
        calculator.setFirstNumber(17);

        
        calculator.setSecondNumber(-290);

        
        System.out.println(calculator.getCalculationResult());

        
        calculator.restorePreviousCalculation(memento);

        
        System.out.println(calculator.getCalculationResult());
    }
}
html
110
-273
110

JDK

  • java.io.Serializable