设计模式(23)——备忘录模式

本文介绍备忘录模式的概念和应用。

基本思想和原则

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

动机

当需要保存一个对象的状态以备之后恢复时,可以使用备忘录模式。这样相当于提供了一个回滚操作,随时可以回滚到之前的状态。

实现

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class Player {
private int hp;

public Player(int hp) {
this.hp = hp;
}

public int getHp() {
return this.hp;
}

public void setHp(int hp) {
this.hp = hp;
}

public Memento createMemento() {
return new Memento(this.hp);
}

public void restoreMemento(Memento memento) {
this.hp = memento.getHp();
}
}

public class Memento {
private int hp;

public Memento(int hp) {
this.hp = hp;
}

public int getHp() {
return this.hp;
}

public void setHp(int hp) {
this.hp = hp;
}
}

public class MementoManager {
private Memento memento;

public MementoManager(Memento memento) {
this.memento = memento;
}

public Memento getMemento() {
return this.memento;
}

public void setMemento(Memento memento) {
this.memento = memento;
}
}

public class Test {
public static void main(String[] args) {
Player player = new Player(100);
MementoManager mementoManager = new MementoManager(player.createMemento());
System.out.println("玩家初始血量:" + player.getHp());
player.setHp(60);
System.out.println("玩家受到攻击,玩家当前血量:" + player.getHp());
player.restoreMemento(mementoManager.getMemento());
System.out.println("读取存档,玩家当前血量:" + player.getHp());
}
}

输出如下:

1
2
3
玩家初始血量:100
玩家受到攻击,玩家当前血量:60
读取存档,玩家当前血量:100

上面代码模拟了玩家初始HP为100,此时进行一次保存(创建一个备忘录),受到攻击后,血量下降,我们直接读取存档,玩家血量恢复到初始状态的场景。

优点

备忘录模式将对象状态的一个备份保存在外部,这样就将对象和这个备份状态解耦了,我们可以随时将对象的状态回滚到之前的某个状态,只要之前这个状态有做备份。

注意事项

使用备忘录模式需要注意的是对象的备份状态如果不需要了应当删除之,否则状态积累越多对内存压力也越大。另外大对象的状态可能很复杂很大,进行一次备份的成本很高,这个也需要适当考虑备份的频度。