设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)

  1. 定义
  2. 应用场景
  3. 优点
  4. 缺点
  5. 角色
  6. 场景模拟
  7. 总结

定义

记录某一时刻的状态,以便用到的时候恢复

应用场景

ctrl+z、快照,回滚,游戏存档,悔棋,相关的备份操作

优点

在需要的时候可以很方便的恢复需要的状态

缺点

频繁保存会消耗大量资源

角色

发起者(Originator):记录状态信息,同时可以访问备忘录中的信息

备忘录(Memento):储存发起人的内部状态

管理者(Caretaker):用于保存和获取备忘录功能,但不能修改

场景模拟

模拟小游戏打怪场景,一个怪2分,可以存档和读档

调用场景实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
//开始游戏
System.out.println("开始游戏,杀死一个小怪得2分");
//开始杀怪
originator.kill();
originator.kill();
//显示目前游戏状态
originator.getScore();
//存档
careTaker.saveMemento(originator.save());
//退出游戏
originator.exit();
//显示目前游戏状态
originator.getScore();
//读档
originator.restoreProcess(careTaker.getMemento(0));
//显示目前游戏状态
originator.getScore();
//在杀
originator.kill();
//显示目前游戏状态
originator.getScore();

输出

1
2
3
4
5
6
7
8
9
10
11
开始游戏,杀死一个小怪得2分
小怪被消灭!获得2分
小怪被消灭!获得2分
目前的游戏数据为:杀了2只怪,分数为4分
存档中...
退出游戏
目前的游戏数据为:杀了0只怪,分数为0分
读档中...
目前的游戏数据为:杀了2只怪,分数为4分
小怪被消灭!获得2分
目前的游戏数据为:杀了3只怪,分数为6分

Originator实现—游戏类

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
public class Originator {
//小怪的数量
private int currentCount;
//小怪单个的价值
private final int value = 2;

//存档
public Memento save() {
System.out.println("存档中...");
return new Memento(currentCount);
}

//恢复分数
public void restoreProcess(Memento memento) {
System.out.println("读档中...");
currentCount = memento.getScore();
}

//杀死一个小怪+2分
public void kill() {
System.out.println("小怪被消灭!获得"+value+"分");
currentCount++;
}

public void getScore(){
System.out.println("目前的游戏数据为:杀了"+currentCount+"只怪,分数为"+currentCount*value+"分");
}

public void exit() {
System.out.println("退出游戏");
currentCount = 0;
}
}

Memento备忘录—游戏对象

1
2
3
4
5
6
7
8
9
10
11
public class Memento {
private int count;

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

public int getScore() {
return count;
}
}

CareTaker管理者—用于存档读档

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

public void saveMemento(Memento memento) {
this.memento.add(memento);
}

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

总结

在JDK、Spring、Mybatis 中很少有备忘录模式,没找到合适的源码场景