目录

备忘录模式

Memento

定义

所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

它实现了对信息的封装,使得客户不需要关心状态保存的细节。保存就要消耗资源,所以备忘录模式的缺点就在于消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

参与者:

  • Originator: 原发器。负责创建一个备忘录,用以记录当前对象的内部状态,通过也可以使用它来利用备忘录恢复内部状态。同时原发器还可以根据需要决定Memento存储Originator的那些内部状态。
  • Memento: 备忘录。用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。在备忘录Memento中有两个接口,其中Caretaker只能看到备忘录中的窄接口,它只能将备忘录传递给其他对象。Originator可以看到宽接口,允许它访问返回到先前状态的所有数据。
  • Caretaker: 负责人。负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。

实现

单状态单备份的例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class Originator {
    private String state = "";     
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public Memento createMemento(){
        return new Memento(this.state);
    }
    public void restoreMemento(Memento memento){
        this.setState(memento.getState());
    }
} 
public class Memento {
    private String state = "";
    public Memento(String state){
        this.state = state;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}
public class Caretaker {
    private Memento memento;
    public Memento getMemento(){
        return memento;
    }
    public void setMemento(Memento memento){
        this.memento = memento;
    }
}
public class Client {
    public static void main(String[] args){
        Originator originator = new Originator();
        originator.setState("状态1");
        System.out.println("初始状态:"+originator.getState());
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(originator.createMemento());
        originator.setState("状态2");
        System.out.println("改变后状态:"+originator.getState());
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("恢复后状态:"+originator.getState());
    }
}

总结

优点

  • 起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。
  • 备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。

缺点:

  • 在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。

如果有需要提供回滚操作的需求,使用备忘录模式非常适合,比如文本编辑器的Ctrl+Z恢复。