设计模式 | 备忘录模式及典型应用

article/2025/11/10 19:00:06

本文的主要内容:

  • 介绍备忘录模式
  • 示例
  • 备忘录模式总结

备忘录模式

备忘录模式经常可以遇到,譬如下面这些场景:

  • 浏览器回退:浏览器一般有浏览记录,当我们在一个网页上点击几次链接之后,可在左上角点击左箭头回退到上一次的页面,然后也可以点击右箭头重新回到当前页面

  • 数据库备份与还原:一般的数据库都支持备份与还原操作,备份即将当前已有的数据或者记录保留,还原即将已经保留的数据恢复到对应的表中

  • 编辑器撤销与重做:在编辑器上编辑文字,写错时可以按快捷键 Ctrl + z 撤销,撤销后可以按 Ctrl + y 重做

  • 虚拟机生成快照与恢复:虚拟机可以生成一个快照,当虚拟机发生错误时可以恢复到快照的样子

  • Git版本管理:Git是最常见的版本管理软件,每提交一个新版本,实际上Git就会把它们自动串成一条时间线,每个版本都有一个版本号,使用 git reset --hard 版本号 即可回到指定的版本,让代码时空穿梭回到过去某个历史时刻

  • 棋牌游戏悔棋:在棋牌游戏中,有时下快了可以悔棋,回退到上一步重新下

浏览器回退

编辑器撤销

备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。它是一种对象行为型模式,其别名为Token。

指针向左为撤销,向右为重做

角色

Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。

Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。

Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

备忘录模式的核心是备忘录类以及用于管理备忘录的负责人类的设计。

示例

下棋例子,可以下棋,悔棋,撤销悔棋等

棋子类 Chessman,原发器角色

@Data
@AllArgsConstructor
class Chessman {private String label;private int x;private int y;//保存状态public ChessmanMemento save() {return new ChessmanMemento(this.label, this.x, this.y);}//恢复状态public void restore(ChessmanMemento memento) {this.label = memento.getLabel();this.x = memento.getX();this.y = memento.getY();}public void show() {System.out.println(String.format("棋子<%s>:当前位置为:<%d, %d>", this.getLabel(), this.getX(), this.getY()));}
}

备忘录角色 ChessmanMemento

@Data
@AllArgsConstructor
class ChessmanMemento {private String label;private int x;private int y;
}

负责人角色 MementoCaretaker

class MementoCaretaker {//定义一个集合来存储备忘录private ArrayList mementolist = new ArrayList();public ChessmanMemento getMemento(int i) {return (ChessmanMemento) mementolist.get(i);}public void addMemento(ChessmanMemento memento) {mementolist.add(memento);}
}

棋子客户端,维护了一个 MementoCaretaker 对象

class Client {private static int index = -1;private static MementoCaretaker mc = new MementoCaretaker();public static void main(String args[]) {Chessman chess = new Chessman("车", 1, 1);play(chess);chess.setY(4);play(chess);chess.setX(5);play(chess);undo(chess, index);undo(chess, index);redo(chess, index);redo(chess, index);}//下棋,同时保存备忘录public static void play(Chessman chess) {mc.addMemento(chess.save());index++;chess.show();}//悔棋,撤销到上一个备忘录public static void undo(Chessman chess, int i) {System.out.println("******悔棋******");index--;chess.restore(mc.getMemento(i - 1));chess.show();}//撤销悔棋,恢复到下一个备忘录public static void redo(Chessman chess, int i) {System.out.println("******撤销悔棋******");index++;chess.restore(mc.getMemento(i + 1));chess.show();}
}

输出如下,悔棋成功,撤销悔棋成功

棋子<车>:当前位置为:<1, 1>
棋子<车>:当前位置为:<1, 4>
棋子<车>:当前位置为:<5, 4>
******悔棋******
棋子<车>:当前位置为:<1, 4>
******悔棋******
棋子<车>:当前位置为:<1, 1>
******撤销悔棋******
棋子<车>:当前位置为:<1, 4>
******撤销悔棋******
棋子<车>:当前位置为:<5, 4>

类图如下

示例.备忘录模式类图

备忘录模式总结

备忘录模式的主要优点如下:

  • 它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

  • 备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

备忘录模式的主要缺点如下:

  • 资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。

适用场景

  • 保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。

  • 防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。

由于JDK、Spring、Mybatis中很少有备忘录模式,也许 Spring webflow 中的 StateManageableMessageContext 接口算一个,但是真的很少见,所以这里不做典型应用源码分析

更多内容请访问我的个人博客:http://laijianfeng.org

关注【小旋锋】微信公众号,及时接收博文推送

关注【小旋锋】微信公众号

推荐阅读

设计模式 | 简单工厂模式及典型应用
设计模式 | 工厂方法模式及典型应用
设计模式 | 抽象工厂模式及典型应用
设计模式 | 建造者模式及典型应用
设计模式 | 原型模式及典型应用
设计模式 | 外观模式及典型应用
设计模式 | 装饰者模式及典型应用
设计模式 | 适配器模式及典型应用
设计模式 | 享元模式及典型应用
设计模式 | 组合模式及典型应用
设计模式 | 模板方法模式及典型应用
设计模式 | 迭代器模式及典型应用
设计模式 | 策略模式及典型应用
设计模式 | 观察者模式及典型应用


http://chatgpt.dhexx.cn/article/pmQQJupa.shtml

相关文章

设计模式之备忘录模式

一、备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;保存一个对象的某个状态&#xff0c;以便在适当的时候恢复对象。备忘录模式属于行为型模式。 原发器(Originator)角色&#xff1a;原发器根据需要决定将自己的哪些内部状态保存到备忘录中&#xff0c;并可以使…

备忘录模式(Java)

备忘录模式&#xff08;Java&#xff09; 下面是关于我所写的所有设计模式代码&#xff08;还是建议自己手打或者想一个别的例子练习一次&#xff09; (https://github.com/lihang212010/DesignPatterns-/tree/master/designpatterns/src) 先来张百度的UML 下面是我例子的U…

撤销功能的实现——备忘录模式(二)

21.2 备忘录模式概述 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&#xff0c;当新的状态无效或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原&#xff0c;当前很多软件都提供了撤销(Undo)操作&#xff0…

18-备忘录模式

文章目录 游戏角色状态恢复问题备忘录模式基本介绍备忘录模式解决游戏角色状态回复问题备忘录模式的注意事项和细节 游戏角色状态恢复问题 游戏鱼色有攻击力和防御力&#xff0c;在大战 Boss 前保存自身的状态&#xff08;攻击力和防御力&#xff09;&#xff0c;当大战 Boss …

详解设计模式:备忘录模式

详解设计模式&#xff1a;备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;也被称为快照模式&#xff08;Snapshot Pattern&#xff09;、Token 模式&#xff08;Token Pattern&#xff09;&#xff0c;是在 GoF 23 种设计模式中定义了的行为型模式。 备忘录模式…

JAVA设计模式--备忘录模式

目录 一、什么是备忘录模式 二、备忘录模式的结构 三、备忘录模式的适用性 四、备忘录模式的实现 五、备忘录模式的优缺点 六、总结 一、什么是备忘录模式 备忘录(Memento)模式又叫作快照(Snapshot)模式或Token模式&#xff0c;是一种对象的行为模式。在备忘录模式里&am…

设计模式之备忘录模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、备忘录模式是什么&#xff1f; 备忘录模式是一种行为型的软件设计模式&#xff0c;在不破坏封装的前提下&#xff0c;获取一个…

什么是备忘录模式?

一、定义 备忘录模式又称快照模式&#xff0c;或者令牌模式。是指在不破坏封装的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态&#xff0c;属于行为型模式。 二、通用写法及其uml 发起人角色&a…

行为型模式——备忘录模式(Memento Pattern)

文章目录 备忘录模式&#xff08;Memento Pattern&#xff09;什么是备忘录模式&#xff1f;UML角色应用使用模板 为什么要使用备忘录模式&#xff1f;优点&#xff1a;缺点&#xff1a; 怎样使用备忘录模式&#xff1f;在JDK中的使用 备忘录模式&#xff08;Memento Pattern&a…

备忘录模式

一、备忘录模式 1、定义 备忘录模式&#xff08;Memento Pattern&#xff09;又称作快照模式&#xff08;Snapshot Pattern&#xff09;&#xff0c;指在不破坏封装的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在对象之外保存这个状态。这样以后就可将该对象恢复…

设计模式系列----备忘录模式

一、什么是备忘录模式 备忘录这个词汇大家应该都不陌生&#xff0c;我就经常使用备忘录来记录一些比较重要的或者容易遗忘的信息&#xff0c;与之相关的最常见的应用有许多&#xff0c;比如游戏存档&#xff0c;我们玩游戏的时候肯定有存档功能&#xff0c;旨在下一次登录游戏时…

基于MIMO讲解信道估计基本原理

为什么要进行信道估计&#xff1f; 信号在通过信道传输的时候&#xff0c;会受到信道中种种因素产生的噪声以及可能发生的多径效应&#xff0c;弄清信号经过的信道的特性&#xff0c;表征信道的技术/过程称为信道估计&#xff08;Channel Estimation&#xff09;。 注&#xf…

m基于深度学习的OFDM信道估计和均衡算法误码率matlab仿真,对比了LS,MMSE以及LMMSE等传统的信道估计算法

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 随着无线通信的快速发展,5G正逐渐成长为支撑全社会各行业运作的大型基础性互联网络,其服务范围的大幅扩展对底层技术提出了诸多挑战,尤其是作为物理层关键技术之一的正交频分复用(Orthogonal Fre…

IRS的信道估计基础代码

一、 智能反射平面&#xff08;intelligent reflecting surfaces&#xff09;是一种被动反射表面&#xff0c;其具有的特性是可控制反射信号的相位。 明确IRS是可控制反射信号的相位&#xff0c;所以以单个智能反射单元为例&#xff0c;该单元可调信号的参数可表示为​&#xf…

信道估计算法

目前我所涉及的是短波宽带无线信道下的接收端的处理&#xff0c;包括捕获、同步、信道估计及信道均衡&#xff0c;还有译码。百度百科里是这样解释这种信道的&#xff1a;短波通信发射电波要经电离层的反射才能到达接收设备&#xff0c;通信距离较远&#xff0c;是远程通信的主…

信道估计之LS算法

信道估计之LS算法 前言LS信道估计的原理总结 前言 信道估计是通信系统接收机的重要功能模块&#xff0c;主要是用来估计信号所经历信道的冲击响应&#xff0c;并用于后续的信道均衡处理&#xff0c;以便消除多径信号混叠造成的ISI。 信道估计的方法有很多种&#xff0c;…

信道估计之LMMSE估计

之前的内容讲到了MMSE信道估计&#xff0c;并推导了基于MMSE优化准则的估计结果&#xff0c;该方法是对LS信道估计的进一步优化&#xff0c;适用于低信噪比场合&#xff0c;但由于其计算复杂&#xff0c;所以并不实用。因此又有了LMMSE信道估计方法&#xff0c;相对于MMSE估计&…

详解信道估计的发展与最新研究进展(MIMO)

目录 一. MIMO信道估计的重要性 二. 最经典的两种信道估计方法 2.1 最小二乘信道估计(LS) 2.2 最小均方误差信道估计(MMSE) 三. 优化传统的MIMO信道估计技术 四. 介绍压缩感知技术 五. 基于压缩感知的MIMO信道估计 5.1 压缩感知怎么用在MIMO信道估计 5.2 改进压缩感知…

c语言差分qpsk编码信道估计 pudn,请教一下OFDM中的信道估计

在AWGN信道中没有多径 这样信道估计和均衡对结果的影响有多少dB呢&#xff1f; 进行了一下仿真&#xff0c;没有加信道编码&#xff0c;用LS信道估计和一阶均衡 附件是仿真的误码率对比图&#xff0c;从图中可以看出均衡似乎对误码率有3dB的恶化 图中横轴是SNR 其中没有均衡的曲…

m基于机器学习MLP的OFDM信道估计误码率matlab仿真,对比LS和MMSE两种信道估计算法

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 信道估计器是接收机一个很重要的组成部分。在OFDM系统中&#xff0c;信道估计器的设计上要有两个问题:一是导频信息的选择&#xff0c;由于无线信道的时变特性&#xff0c;需要接收机不断对信道进…