Java设计模式之行为型模式(备忘录模式)实现方式与测试用例
最近看到一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站
一、实现方式
- 基础结构与角色定义
备忘录模式包含三个核心角色,协作关系如下:
- Originator(发起人):需保存/恢复状态的对象,提供创建和恢复备忘录的方法。
- Memento(备忘录):存储发起人状态的载体,通常设计为不可变类。
- Caretaker(管理者):管理备忘录对象,不操作其内容。
代码示例(文本编辑器场景):
// 发起人:文本编辑器
public class Editor {private String content;// 创建备忘录public Memento save() {return new Memento(content);}// 从备忘录恢复状态public void restore(Memento memento) {this.content = memento.getState();}
}
// 备忘录:存储状态(不可变)
public class Memento {private final String state;public Memento(String state) { this.state = state; }public String getState() { return state; }
}
// 管理者:保存备忘录列表
public class History {private List mementos = new ArrayList<>();public void add(Memento memento) { mementos.add(memento); }public Memento get(int index) { return mementos.get(index); }
}
- 高级实现技巧
- 多级撤销与重做:使用栈结构管理备忘录。
public class AdvancedHistory {private Stack undoStack = new Stack<>();private Stack redoStack = new Stack<>();public void push(Memento memento) { undoStack.push(memento); }public Memento undo() { return undoStack.pop(); }public void redo(Memento memento) { redoStack.push(memento); } }
- 资源优化:通过序列化持久化备忘录。
// 发起人支持序列化 public class SerializableOriginator extends Originator implements Serializable {private String state; }
二、测试用例设计
- 基础功能验证
目标:验证状态保存与恢复的正确性。
public class MementoTest {@Testpublic void testStateRecovery() {Editor editor = new Editor();History history = new History();editor.setContent("Initial text");history.add(editor.save()); // 保存状态1editor.setContent("Modified text");history.add(editor.save()); // 保存状态2// 恢复到状态1editor.restore(history.get(0));assertEquals("Initial text", editor.getContent());}
}
- 异常场景测试
目标:验证空备忘录或非法操作的容错性。
@Test(expected = IllegalStateException.class)
public void testRestoreNullMemento() {Editor editor = new Editor();editor.restore(null); // 触发异常
}
- 多级撤销测试
目标:验证栈结构管理的撤销/重做功能。
@Test
public void testUndoRedo() {Editor editor = new Editor();AdvancedHistory history = new AdvancedHistory();editor.setContent("State 1");history.push(editor.save());editor.setContent("State 2");history.push(editor.save());// 撤销到状态1editor.restore(history.undo());assertEquals("State 1", editor.getContent());// 重做到状态2history.redo(editor.save());assertEquals("State 2", editor.getContent());
}
- 性能与资源测试
目标:监控内存占用与优化策略有效性。
@Test
public void testMemoryOptimization() {Originator originator = new Originator();Caretaker caretaker = new Caretaker();// 生成1000个备忘录for (int i = 0; i < 1000; i++) {originator.setState("State #" + i);caretaker.add(originator.saveStateToMemento());}// 断言内存占用符合预期(需结合Profiler工具)assertTrue(memoryUsage < MAX_ALLOWED_MEMORY);
}
三、关键设计原则
- 封装性保护:
Memento
类仅对Originator
开放宽接口,其他类仅通过Caretaker
管理。
- 职责分离:
- 状态管理由
Caretaker
负责,状态逻辑由Originator
实现。
- 状态管理由
- 资源控制:
- 限制备忘录数量(如仅保存最近10个状态)或使用增量存储。
四、实际应用示例
场景:游戏存档系统
// 发起人:游戏角色
public class Gamer {private int level;private Inventory items;public GamerMemento save() {return new GamerMemento(level, items.clone());}public void restore(GamerMemento memento) {this.level = memento.getLevel();this.items = memento.getItems();}// 备忘录类(内部类)public static class GamerMemento {private final int level;private final Inventory items;// 构造函数与Getter}
}
// 测试用例
@Test
public void testGameSaveLoad() {Gamer gamer = new Gamer();History history = new History();gamer.setLevel(5);history.add(gamer.save());gamer.setLevel(10);gamer.restore(history.get(0));assertEquals(5, gamer.getLevel());
}
五、总结
备忘录模式通过状态快照与封装隔离机制,为撤销、回滚等场景提供了灵活的解决方案。实现时需注重:
- 角色职责的清晰划分。
- 资源管理策略(如栈结构、序列化)。
- 全覆盖测试用例设计,确保状态一致性与容错性。
该模式广泛应用于编辑器、游戏、数据库等领域,是实现无副作用状态管理的核心工具。