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

设计模式之备忘录模式

        在日常开发中,我们经常会遇到这样的场景:需要保存对象的某个历史状态,以便将来恢复。这种需求最常见的例子就是“撤销操作”。在这种情况下,备忘录模式(Memento Pattern)就派上了用场。

目录

1. 概念

2. 代码实现

3. 总结


1. 概念

        备忘录模式属于行为型设计模式。它的核心思想是:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态。

        通俗点讲,备忘录模式就像是在玩游戏时存档:你保存了一个状态,之后可以随时“读档”回来。

备忘录模式包含三个关键角色:

1. Originator(发起人):需要保存状态的对象

2. Memento(备忘录):用来存储对象的内部状态

3. Caretaker(管理者):负责保存备忘录,但不会操作或检查其内容

2. 代码实现

        这里我将采用一个编辑/撤销文本的案例来实现备忘录模式。

首先我准备一个Editor类

public class Editor {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;}}
}

这里我定义了一个静态内部类即Memento类,主要作为一个备忘录,也是被记录的状态类。

接下来再定义管理者,负责管理备忘录:

import java.util.Stack;public class History {private final Stack<Editor.Memento> history = new Stack<>();public void push(Editor.Memento memento) {history.push(memento);}public Editor.Memento pop() {if (!history.isEmpty()) {return history.pop();}return null;}
}

这里我们这个管理类也基于栈来实现,其后进先出的特性可以很好的实现我们需要的写入撤销的业务逻辑。

最后完成一个主测试类:

public class MementoDemo {public static void main(String[] args) {Editor editor = new Editor();History history = new History();editor.setText("Version 1");history.push(editor.save());editor.setText("Version 2");history.push(editor.save());editor.setText("Version 3");System.out.println("当前内容: " + editor.getText()); // 输出 Version 3editor.restore(history.pop());System.out.println("撤销后: " + editor.getText()); // 输出 Version 2editor.restore(history.pop());System.out.println("再次撤销: " + editor.getText()); // 输出 Version 1}
}

3. 总结

        备忘录模式的封装良好,但其实在实际工作中用到的地方并没有很多,绝大多数的游戏服务器实现存档的功能类似备忘录模式,但是对于后端服务器业务开发过程中,此设计模式的实践并不是很多,大家可以作为了解即可。

http://www.xdnf.cn/news/7583.html

相关文章:

  • 通过COM获取正在运行的Excel实例并关闭 c#实现
  • C++之set与map介绍
  • JavaScript 日志和调试工具箱-logger2js
  • 数据仓库是什么?常见问题解答
  • ELK简介和docker版安装
  • 硬件工程师笔记——三极管Multisim电路仿真实验汇总
  • 深入浅出:Spring Cloud Gateway 扩展点实践指南
  • Zookeeper 集群安装与脚本化管理详解
  • 【笔记】与PyCharm官方沟通解决开发环境问题
  • 测试W5500的第2步_使用ioLibrary库创建TCP客户端
  • 【razor】回环结构导致的控制信令错位:例如发送端收到 SR的问题
  • k8s 配置 Kafka SASL_SSL双重认证
  • 计算机网络基础概念
  • 新能源汽车焊接智能节气阀
  • uni-app 中使用 mumu模拟器 进行调试和运行详细教程
  • Matplotlib 高级进阶实战:多维度数据可视化组合图表
  • nbufxz动态规划1
  • 零基础设计模式——创建型模式 - 工厂方法模式
  • 【课堂笔记】核方法和Mercer定理
  • [Java实战]Spring Boot整合Sentinel:流量控制与熔断降级实战(二十九)
  • 数据集划分与格式转换:从原始数据到模型训练的关键步骤
  • 在 Excel 中使用通义灵码辅助开发 VBA 程序
  • 自学嵌入式 day21 - 数据结构 双向链表
  • 全局对比度调整
  • MCP 协议传输机制大变身:抛弃 SSE,投入 Streamable HTTP 的怀抱
  • taro 小程序 CoverImage Image src无法显示图片的问题
  • 剧本杀小程序:指尖上的沉浸式推理宇宙
  • 【Linux笔记】——线程同步信号量与环形队列生产者消费者模型的实现(PV操作)
  • shp2pgsql 导入 Shp 到 PostGIS 空间数据库
  • MATLAB中进行语音信号分析