Java备忘录模式
备忘录模式保存对象内部状态,以便以后恢复。
模式定义
意图:在不破坏封装前提下,捕获对象内部状态,以便以后恢复。
适用场景
- 需要保存/恢复对象状态
- 撤销功能
- 事务回滚
- 游戏存档
模式结构
备忘录类
Java
public class Memento {
private String state; // 状态快照
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
发起人类
Java
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
// 创建备忘录
public Memento createMemento() {
return new Memento(state);
}
// 从备忘录恢复
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
}
管理人类
Java
public class Caretaker {
private List<Memento> mementos = new ArrayList<>();
public void addMemento(Memento memento) {
mementos.add(memento);
}
public Memento getMemento(int index) {
return mementos.get(index);
}
public Memento getLastMemento() {
if (!mementos.isEmpty()) {
return mementos.get(mementos.size() - 1);
}
return null;
}
}
使用示例
Java
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("状态1");
caretaker.addMemento(originator.createMemento());
originator.setState("状态2");
caretaker.addMemento(originator.createMemento());
originator.setState("状态3");
System.out.println("当前状态: " + originator.getState()); // 状态3
// 恢复到状态2
originator.restoreMemento(caretaker.getMemento(1));
System.out.println("恢复后: " + originator.getState()); // 状态2
// 恢复到状态1
originator.restoreMemento(caretaker.getMemento(0));
System.out.println("恢复后: " + originator.getState()); // 状态1
实际应用示例
文本编辑器
Java
public class TextEditor {
private String text;
public void write(String text) {
this.text = text;
}
public String getText() {
return text;
}
public TextMemento save() {
return new TextMemento(text);
}
public void restore(TextMemento memento) {
this.text = memento.getText();
}
}
public class TextMemento {
private String text;
public TextMemento(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
public class History {
private Stack<TextMemento> history = new Stack<>();
public void push(TextMemento memento) {
history.push(memento);
}
public TextMemento pop() {
return history.isEmpty() ? null : history.pop();
}
}
// 使用
TextEditor editor = new TextEditor();
History history = new History();
editor.write("Hello");
history.push(editor.save());
editor.write("Hello World");
history.push(editor.save());
editor.write("Hello World!");
System.out.println(editor.getText()); // Hello World!
// 撤销
editor.restore(history.pop());
System.out.println(editor.getText()); // Hello World
游戏存档
Java
public class GameRole {
private int hp;
private int mp;
private int level;
public void setHp(int hp) { this.hp = hp; }
public void setMp(int mp) { this.mp = mp; }
public void setLevel(int level) { this.level = level; }
public RoleMemento saveState() {
return new RoleMemento(hp, mp, level);
}
public void restoreState(RoleMemento memento) {
this.hp = memento.getHp();
this.mp = memento.getMp();
this.level = memento.getLevel();
}
public void display() {
System.out.println("HP:" + hp + " MP:" + mp + " Level:" + level);
}
}
public class RoleMemento {
private int hp;
private int mp;
private int level;
public RoleMemento(int hp, int mp, int level) {
this.hp = hp;
this.mp = mp;
this.level = level;
}
public int getHp() { return hp; }
public int getMp() { return mp; }
public int getLevel() { return level; }
}
备忘录封装性
备忘录只应被发起人访问,可通过内部类实现:
Java
public class Originator {
private String state;
// 内部类备忘录,外部无法访问
public class Memento {
private String state;
private Memento(String state) {
this.state = state;
}
private String getState() {
return state;
}
}
public Memento createMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
}
备忘录模式优点
- 不破坏封装保存状态
- 简化状态恢复逻辑
- 支持多次撤销
备忘录模式缺点
- 备忘录占用内存
- 管理备忘录增加复杂度
注意事项
备忘录应只对发起人开放
大对象状态保存考虑内存开销
可结合命令模式实现撤销重做
状态过多时可选择性保存关键状态
要点总结
- 备忘录模式保存对象状态以便恢复
- Originator创建和恢复备忘录
- Caretaker管理备忘录,不修改内容
- 备忘录应保持封装性,只对发起人开放
- 适用于撤销功能、事务回滚、游戏存档
📝 发现内容有误?点击此处直接编辑