首页 > 编程笔记 > Java笔记 阅读:4

备忘录模式(Java实现,附带实例)

有的时候,我们可能要保存与对象状态有关的少量信息,以便将来把该对象恢复到它应有的状态。备忘录模式所提供的正是这个功能,它属于经典的 GoF(Gang of Four)设计模式。

备忘录(memento)让我们在不破坏封装的前提下,捕获对象的内部状态并将其交给外界,使得外界稍后可以将该对象恢复到制作备忘录时的样子。

备忘录模式向用户提供了一套功能,令其可以根据需求随时使用早前制作的备忘录,将对象恢复到想要的状态。

备忘录模式在JDK中的运用

Date 类就是备忘录模式的典型范例,它位于 java.base 模块的 java.util 包中。

你可以让 Date 类的实例先指向某个特定的时间点,然后修改这个实例的状态,令其表示其他的时间点,最后再将其恢复到早前的那个时间点上(用 Date 表示日期与时间的时候,还可以根据历法和时区将同一个时刻表示成不同的形式)。

备忘录模式实例演示

我们以车里的空调为例。假设空调提供了多个挡位,用来调整驾驶室的温度,另外还提供记忆功能,让司机能够根据早前的某一份记录将挡位恢复到当时的状态(司机需要指出那份记录的序号),参见下面的实例。

【实例】司机能够随时将空调的状态制作成备忘录,并根据某份备忘录把空调恢复到当时的状态。
public static void main(String[] args) {
    System.out.println("Memento Pattern, air-condition system");
    var originator = new AirConditionSystemOriginator();
    var careTaker = new AirConditionSystemCareTaker();

    originator.setState("low");
    var stateLow = originator.saveState(careTaker);
    originator.setState("medium");
    var stateMedium = originator.saveState(careTaker);
    originator.setState("high");
    var stateHigh = originator.saveState(careTaker);

    System.out.printf("\n\nCurrent Air-Condition System state:'%s'\n\n", originator.getState());

    originator.restoreState(careTaker.getMemento(stateLow));
    System.out.printf("\n\nRestored position:'%d', Air-Condition System state:'%s'\n\n", stateLow, originator.getState());
}
程序输出结果如下:

Memento Pattern, air-condition system
Current Air-Condition System state:'high'
Restored position:'0', Air-Condition System state:'low'

AirConditionSystemCareTaker 类的实例在本例中扮演备忘录提供方(memento provider),也可以理解为备忘录管理器,它包含已经制作好的备忘录,并且通过 getMemento() 方法向用户提供(参见下面的范例)。

【实例】每次保存状态都会形成一个标识码用于恢复对象状态。
final class AirConditionsSystemCareTaker {
    private final List<SystemMemento> memory = new ArrayList<>();

    ...
    int add(SystemMemento m) { ... }

    SystemMemento getMemento(int i) { ... }
}
AirConditionSystemOriginator 类的实例负责把对象的当前状态创建成备忘录,还负责根据某份备忘录恢复对象的状态。用户通过该类的 saveState() 方法创建备忘录时,需要把它所返回的备忘录序号(也就是状态标识码)记住,因为稍后恢复状态时,需要通过这个序号从 AirConditionSystemCareTaker 里把相应的备忘录取出来,并交给 originator 的 restoreState() 方法去执行恢复(参见下面的实例)。

【实例】AirConditionSystemOriginator 记录空调的状态,提供制作备忘录的功能,并把这份备忘录的序号返回给用户。
final class AirConditionsSystemOriginator {
    private String state;

    ...
    int saveState(AirConditionsSystemCareTaker careTaker) {
        return careTaker.add(new SystemMemento(state));
    }

    void restoreState(SystemMemento m) {
        state = m.state();
    }
}
备忘录模式让用户能够通过备忘录机制方便地记录并恢复对象状态。这样的话,用户就不用手工创建其他一些用来记录状态的东西了(参见下图)。


图 1 用UML类图来演示几个类

备忘录模式能够帮助程序执行撤销(undo)操作,或者令其状态退回到早前的某个时间点。该模式让我们能够清晰地实现这些功能,并将不同的逻辑划分开,使得程序的代码更容易维护。

相关文章