备忘录模式
备忘录模式(Memento Pattern)是一种行为设计模式,它允许对象在不影响其封装性的前提下,捕获并外部化其内部状态,并且可以在将来恢复到之前保存的状态。这种模式非常适合实现撤销/重做功能、保存及恢复状态等场景。
类图
角色
备忘录模式主要包括以下三个角色:
- 发起人(Originator):负责创建一个包含其当前内部状态的备忘录,并能够使用该备忘录恢复其内部状态。
- 备忘录(Memento):负责存储发起人的内部状态,并防止其他对象访问备忘录。备忘录可以有两个接口,一个是窄接口(只能由负责人使用),另一个是宽接口(只能由发起人使用)。
- 负责人(Caretaker):负责保存好备忘录,但不能操作或检查备忘录的内容。
使用场景
- 撤销/重做功能:如文本编辑器中的撤销操作。
- 游戏状态保存与恢复:例如保存游戏进度,允许玩家返回之前的游戏状态。
- 配置设置备份:在软件配置更改前后保存状态,以便用户可以恢复到之前的设置。
- 事务管理:数据库操作中的事务回滚功能。
适用场景
功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。
优缺点
优点
- 提供了状态恢复的能力,简化了状态管理的复杂度。
- 改善了封装性,状态的存储由备忘录类管理,原发器类的内部细节不会暴露给其他对象。
- 支持多次撤销操作,增强程序的灵活性和健壮性。
缺点
- 如果状态复杂,可能会占用较大的内存空间。
- 需要谨慎设计以避免备忘录对象包含过多不必要的信息,导致资源浪费。
示例
java
package com.justin.memento.textedit;
import java.util.ArrayList;
import java.util.List;
// 发起人
class TextEditor {
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public Memento save() {
return new Memento(text);
}
public void restore(Memento memento) {
this.text = memento.getText();
}
// 备忘录
public static class Memento {
private final String text;
private Memento(String text) {
this.text = text;
}
private String getText() {
return text;
}
}
}
// 负责人
class Caretaker {
private final List<TextEditor.Memento> mementoList = new ArrayList<>();
public void addMemento(TextEditor.Memento memento) {
mementoList.add(memento);
}
public TextEditor.Memento getMemento(int index) {
return mementoList.get(index);
}
}
// 测试
public class Test {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
Caretaker caretaker = new Caretaker();
editor.setText("Version 1");
caretaker.addMemento(editor.save());
editor.setText("Version 2");
caretaker.addMemento(editor.save());
editor.setText("Version 3");
System.out.println("Current Text: " + editor.getText());
editor.restore(caretaker.getMemento(1));
System.out.println("Restored to: " + editor.getText());
editor.restore(caretaker.getMemento(0));
System.out.println("Restored to: " + editor.getText());
}
}