当前位置: 首页 > backend >正文

Java设计模式之行为型模式(备忘录模式)实现方式与测试用例

最近看到一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

一、实现方式

  1. 基础结构与角色定义
    备忘录模式包含三个核心角色,协作关系如下:
  • 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); }
}
  1. 高级实现技巧
  • 多级撤销与重做:使用栈结构管理备忘录。
    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;
    }
    

二、测试用例设计

  1. 基础功能验证
    目标:验证状态保存与恢复的正确性。
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());}
}
  1. 异常场景测试
    目标:验证空备忘录或非法操作的容错性。
@Test(expected = IllegalStateException.class)
public void testRestoreNullMemento() {Editor editor = new Editor();editor.restore(null);  // 触发异常
}
  1. 多级撤销测试
    目标:验证栈结构管理的撤销/重做功能。
@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());
}
  1. 性能与资源测试
    目标:监控内存占用与优化策略有效性。
@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);
}

三、关键设计原则

  1. 封装性保护:
    • Memento类仅对Originator开放宽接口,其他类仅通过Caretaker管理。
  2. 职责分离:
    • 状态管理由Caretaker负责,状态逻辑由Originator实现。
  3. 资源控制:
    • 限制备忘录数量(如仅保存最近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());
}

五、总结

备忘录模式通过状态快照与封装隔离机制,为撤销、回滚等场景提供了灵活的解决方案。实现时需注重:

  1. 角色职责的清晰划分。
  2. 资源管理策略(如栈结构、序列化)。
  3. 全覆盖测试用例设计,确保状态一致性与容错性。
    该模式广泛应用于编辑器、游戏、数据库等领域,是实现无副作用状态管理的核心工具。
http://www.xdnf.cn/news/15840.html

相关文章:

  • 【Unity3D实例-功能-移动】角色移动-通过WSAD(CharacterController方式)
  • 第四次作业
  • haproxy七层代理
  • 嵌入式硬件篇---继电器
  • C#.NET EFCore.BulkExtensions 扩展详解
  • 物联网安装调试-温湿度传感器
  • 分布式文件系统04-DataNode海量数据分布式高可靠存储
  • python中读取 Excel 表格数据
  • 【数据结构】揭秘二叉树与堆--用C语言实现堆
  • 【MySQL】索引中的页以及索引的分类
  • LLVM中AST节点类型
  • string【下】- 补充
  • MySQL中的排序和分页
  • 集群与高可用
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 饱和预测 Saturating Forecasts
  • Go并发聊天室:从零构建实战
  • Shell脚本-tee工具
  • 小程序和H5数据mock配置过程
  • 前端环境搭建---基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建
  • LLM 的Top-P参数 是在LLM中的每一层发挥作用,还是最后一层?
  • SpringBoot五分钟快速入门指南
  • NW993NX584美光固态闪存NX559NX561
  • [故障诊断方向]基于二维时频图像和数据增强技术的轴承故障诊断模型
  • 数据分析综合应用 30分钟精通计划
  • 动态规划——数位DP经典题目
  • 量子计算与AI融合的技术突破与实践路径
  • 6. 装饰器模式
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pillow’问题
  • 小架构step系列19:请求和响应
  • Java行为型模式---中介者模式