备忘录模式
# 备忘录模式
# 定义
备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不破坏封装性的前提下捕获和恢复一个对象的内部状态。
# 结构
发起人(Originator):需要被保存状态以便恢复的那个对象,负责创建一个备忘录对象,用于记录当前状态,并可以使用备忘录对象恢复到之前的状态。
备忘录(Memento):负责存储发起人对象的内部状态。备忘录可以包含发起人的一部分或全部状态信息,该对象由发起人创建。
管理者(Caretaker):负责保存备忘录对象,并在需要时将备忘录提供给发起人进行状态恢复。
- img: https://bitouyun.com/images/design-pattern/memento.png
link: https://bitouyun.com/images/design-pattern/memento.png
name: 备忘录模式
2
3
# 优点
简化发起人对象:备忘录模式可以将发起人对象的状态保存和恢复的职责转移到备忘录对象和管理者对象上,从而简化了发起人对象的代码。发起人对象只需关注自身的核心业务,而不必承担状态管理的责任。
提供状态历史记录:备忘录模式可以方便地记录对象的状态历史,使得对象可以轻松实现撤销、恢复、重做等功能。这对于需要维护对象状态变化历史的应用场景非常有用。
封装性好:备忘录模式通过将状态封装在备忘录对象中,实现了对对象状态的保护和封装。外部无法直接访问备忘录对象,从而确保了对象状态的安全性和一致性。
# 缺点
备忘录对象管理复杂:如果发起人对象的状态非常庞大或频繁变化,会导致备忘录对象的创建和管理变得复杂。在需要保存大量历史记录的情况下,可能会占用较多的内存。
潜在的性能损失:备忘录模式可能会带来一定的性能损失。每次保存状态都需要创建备忘录对象,并将状态存储在备忘录中,这涉及对象的拷贝操作或序列化操作,可能会对性能产生一定的影响。
# 应用场景
撤销和恢复功能:当需要实现对象状态的撤销和恢复功能时,备忘录模式是一个常用的解决方案。通过将对象的状态保存到备忘录对象中,可以在需要时将对象恢复到之前的状态,实现撤销和恢复的功能。
编辑器和文档应用:在编辑器或文档应用中,备忘录模式可以用于保存编辑操作的历史记录。这样用户可以撤销和恢复之前的操作,例如撤销一次文本修改、恢复到之前的保存点等。
游戏状态管理:在游戏开发中,备忘录模式可以用于保存游戏状态的快照,以便在需要时恢复到之前的状态。例如,保存游戏进度、撤销一次游戏操作等。
数据库事务管理:在数据库应用中,备忘录模式可以用于实现事务的回滚功能。当执行数据库操作时,可以将数据库的状态保存到备忘录对象中,如果操作失败或需要回滚,可以使用备忘录对象恢复到之前的状态。
历史记录和日志功能:备忘录模式可以用于记录对象的状态历史,实现历史记录和日志功能。通过保存对象状态的备忘录对象,可以方便地获取对象状态的变化历史,并进行回放、分析或日志记录。
# 示例代码
场景
使用备忘录模式实现游戏的存档和读档功能,游戏中的玩家可以通过备忘录模式保存当前游戏状态,并在需要时恢复到之前的状态。
/**
* 游戏
* 发起人类,负责创建备忘录对象记录当前游戏状态和恢复状态。
*/
@Slf4j
public class Game {
private int level;
private int score;
public void play() {
level++;
score += 100;
log.info("等级:{},得分:{}", level, score);
}
// 创建备忘录
public GameMemento createMemento() {
return new GameMemento(level, score);
}
// 恢复备忘录
public void restoreMemento(GameMemento gameMemento) {
level = gameMemento.getLevel();
score = gameMemento.getScore();
}
}
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
/**
* 游戏备忘录类
* 保存发起人(Game)对象的游戏状态,包括等级和得分。
*/
public class GameMemento {
private int level;
private int score;
public GameMemento(int level, int score) {
this.level = level;
this.score = score;
}
public int getLevel() {
return level;
}
public int getScore() {
return score;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 存档管理者
* 管理者类,负责保存备忘录对象,并在需要时将其提供给发起人进行状态恢复。
*/
public class SaveManager {
private GameMemento gameMemento;
// 保存备忘录
public void saveMemento(GameMemento gameMemento) {
this.gameMemento = gameMemento;
}
// 检索备忘录
public GameMemento retrieveMemento() {
return gameMemento;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 发起人
Game game = new Game();
// 存档管理者
SaveManager saveManager = new SaveManager();
// 玩游戏
game.play();
// 保存当前游戏状态
saveManager.saveMemento(game.createMemento());
// 玩游戏
game.play();
// 恢复到之前的游戏状态
game.restoreMemento(saveManager.retrieveMemento());
// 玩游戏
game.play();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Make sure to add code blocks to your code group