1. 意图(Intent)
在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。
2. 类图(Class Diagram)

- Originator:原始对象
- Caretaker :负责保存好备忘录
- Memento :备忘录,存储原始对象的状态。备忘录实际上有两个接口
1. 一个是提供给 Caretaker 的窄接口,它只能将备忘录传递给其它对象;1. 一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。
3. 实现(Implementation)
以下实现了一个简单计算器程序,可以输入两个值,然后计算这两个值的和。备忘录模式允许将这两个值存储起来,然后在某个时刻用存储的状态进行恢复。
操作方法接口 (定义了对原始对象的操作方法)
public interface Calculator {
// 创建备忘录
PreviousCalculationToCareTaker backupLastCalculation();
// 创建备忘录
void restorePreviousCalculation(PreviousCalculationToCareTaker memento);
int getCalculationResult();
void setFirstNumber(int firstNumber);
void setSecondNumber(int secondNumber);
}
实现了接口方法的计算实现类 (实现了具体的方法,如何对原始对象 Originator 进行操作)
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() {
// 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;
}
}
针对原始对象进行备忘方法接口 [ Originator ]
// 该接口允许发起者恢复其状态
public interface PreviousCalculationToOriginator {
int getFirstNumber();
int getSecondNumber();
}
负责保存备忘录的接口 [ Caretaker ]
// 负责保存好备忘录
public interface PreviousCalculationToCareTaker {
// no operations permitted for the caretaker (caretaker不允许进行任何操作)
}
备忘录实现类 [ Memento ]
// 请注意,此对象同时实现了 Originator 和 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;
}
}
客户端演示代码:
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());
// 用户按 CTRL + Z 撤消上次操作并查看上次结果
calculator.restorePreviousCalculation(memento);
// 恢复之前结果
System.out.println(calculator.getCalculationResult());
}
}
输出:
110
-273
110
4. JDK
- java.io.Serializable
