备忘录设计模式(Memento Pattern)

描述: 备忘录设计模式是行为型设计模式之一,该设计模式用于保存对象当前的状态,并且在之后可以再次恢复到此状态,以便在适当的时候恢复此状态

核心思想: 在不破坏封装的前提, 保存一个对象在某一个时刻的状态或者部分状态

使用场景:

  • 需要保存恢复数据的相关状态场景
  • 提供一个可回滚的操作
  • 可以使用于快照功能

备忘录设计模式的优点

  • 给用户提供了一种可以恢复状态的机制,可以使用户比较方便的回滚到某个历史状态
  • 实现了历史的封装,使用户不用关心状态保存的细节

备忘录设计模式的缺点:

  • 消耗资源,如果类的成员过多会占用比较大的资源,每一次保存都会消耗一定的内存

示例:

  • 备忘录
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
class Memento {

private int menoy;
private ArrayList<String> fruits;

//窄接口,访问部分信息
public int getMenoy() {
return menoy;
}

//宽接口,本包之内皆可访问
Memento(int menoy) {
this.menoy = menoy;
fruits = new ArrayList();//每次调用的时候重新生成,很重要
}

//宽接口,本包之内皆可访问
List getFruits() {
return (List) fruits.clone();
}

//宽接口,本包之内皆可访问
void addFruits(String fruit) {
fruits.add(fruit);
}

@Override
public String toString() {
return "Menoy:" + menoy + " ,Fruits:" + fruits;
}
}
  • 原对象
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
@Data
class Gamer {
private int menoy;
private List<String> fruits;
private int name;
public int getMenoy() {
return menoy;
}

public Gamer(int menoy) {
this.menoy = menoy;
}


public Memento createMemento() {
Memento m = new Memento(menoy);
fruits.stream().filter(x -> x.startsWith("好吃")).forEach(x -> {
m.addFruits(x);
});
return m;
}

public void restoreMemento(Memento memento) {
this.menoy = memento.getMenoy();
this.fruits = memento.getFruits();
}

}

  • 客户端使用
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
public class Test {
public static void main(String[] args) {
Gamer gamer = new Gamer(100);
Memento memento = null;
ArrayList<String> list = new ArrayList<>();
list.add("好吃的苹果");
list.add("梨");
list.add("好吃的橘子");
list.add("香蕉");
gamer.setFruits(list);
System.out.println("我是原本的" + gamer);

Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int i = scanner.nextInt();
if (i == 1) {
memento = gamer.createMemento();
}
if (i == 2) {
gamer.restoreMemento(memento);
System.out.println("我是回退的:" + gamer);
}
}
}
}