Zer0e's Blog

设计模式之备忘录模式

字数统计: 632阅读时长: 2 min
2020/09/06 Share

前言

本篇来谈谈备忘录模式。

正文

概念

备忘录模式保存对象的某个状态,以便当需要时恢复这个状态,它属于行为型模式。
它又称快照模式或token模式。它的意图是在不破坏封装的条件下,将对象的状态保存下来,并存储,并且可以在未来的某个时刻恢复。
这个模式涉及三个角色:

  • 备忘录(Memento):将发起人对象的内部状态存储起来,并且可以保护不被发起人以外的对象所读取。
  • 发起人(Originator):创建一个含有内部状态的备忘录对象,并存储自己的内部状态。
  • 负责人(Caretaker):负责保存备忘录对象,不检查备忘录对象的内容。

实现

我们先创建备忘录(Memento),这里对象的内部状态我们使用string来表示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}
}

创建发起人(Originator):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Originator {
private String state;

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public Memento savaStateToMemento(){
return new Memento(state);
}
public void getStateFromMemento(Memento memento){
state = memento.getState();
}
}

创建负责人(Caretaker),负责保存备忘录对象,这里用list存储一系列状态。

1
2
3
4
5
6
7
8
9
10
public class Caretaker {
private List<Memento> mementoList = new ArrayList<>();

public Memento retrieveMemento(int index){
return mementoList.get(index);
}
public void saveMemento(Memento memento){
mementoList.add(memento);
}
}

创建客户端,并设置一下状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();

originator.setState("state 1");
caretaker.saveMemento(originator.savaStateToMemento());

originator.setState("state 2");
caretaker.saveMemento(originator.savaStateToMemento());


originator.getStateFromMemento(caretaker.retrieveMemento(0));
System.out.println(originator.getState());

originator.getStateFromMemento(caretaker.retrieveMemento(1));
System.out.println(originator.getState());

}
}

这里我们设置两个状态,并拍摄快照,最后依次恢复快照查看状态。

使用场景

上文也提过,这个模式适合拍摄快照,例如游戏存档,可以将玩家的某个状态存储,并适时的时候恢复。还有就是提供可回滚的操作,等等。

优缺点

那备忘录模式的优点是给用户提供了一种可恢复的机制,可以较为方便地回到某个时间点。其次就是调用者无需关心如何保存状态。
那缺点也很明显,就是占用内存或空间,如果类的状态和变量过多,则会消耗一定的资源。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 使用场景
    4. 2.4. 优缺点