设计模式 - 备忘录模式
目录
一. 前言
二. 实现
三. 优缺点
一. 前言
备忘录模式又称快照模式,是一种行为型设计模式。它可以在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要的时候恢复到原先保存的状态。在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。
二. 实现

Originator:原始对象。
Caretaker:负责保存好备忘录。
Menento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口,它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。
案例:以下实现了一个简单计算器程序,可以输入两个值,然后计算这两个值的和。备忘录模式允许将这两个值存储起来,然后在某个时刻用存储的状态进行恢复。
/*** Originator Interface*/
public interface Calculator {// Create MementoPreviousCalculationToCareTaker backupLastCalculation();// setMementovoid restorePreviousCalculation(PreviousCalculationToCareTaker memento);int getCalculationResult();void setFirstNumber(int firstNumber);void setSecondNumber(int secondNumber);
}
/*** Originator Implementation*/
public class CalculatorImp implements Calculator {private int firstNumber;private int secondNumber;@Overridepublic PreviousCalculationToCareTaker backupLastCalculation() {// create a memento object used for restoring two numbersreturn new PreviousCalculationImp(firstNumber, secondNumber);}@Overridepublic void restorePreviousCalculation(PreviousCalculationToCareTaker memento) {this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();}@Overridepublic int getCalculationResult() {// result is adding two numbersreturn firstNumber + secondNumber;}@Overridepublic void setFirstNumber(int firstNumber) {this.firstNumber = firstNumber;}@Overridepublic void setSecondNumber(int secondNumber) {this.secondNumber = secondNumber;}
}
/*** Memento Interface to Originator** This interface allows the originator to restore its state*/
public interface PreviousCalculationToOriginator {int getFirstNumber();int getSecondNumber();
}/*** Memento interface to CalculatorOperator (Caretaker)*/
public interface PreviousCalculationToCareTaker {// no operations permitted for the caretaker
}
/*** Memento Object Implementation* <p>* Note that this object implements both interfaces to Originator and CareTaker*/
public class PreviousCalculationImp implements PreviousCalculationToCareTaker,PreviousCalculationToOriginator {private int firstNumber;private int secondNumber;public PreviousCalculationImp(int firstNumber, int secondNumber) {this.firstNumber = firstNumber;this.secondNumber = secondNumber;}@Overridepublic int getFirstNumber() {return firstNumber;}@Overridepublic int getSecondNumber() {return secondNumber;}
}
/*** CareTaker object*/
public class Client {public static void main(String[] args) {// program startsCalculator calculator = new CalculatorImp();// assume user enters two numberscalculator.setFirstNumber(10);calculator.setSecondNumber(100);// find resultSystem.out.println(calculator.getCalculationResult());// Store result of this calculation in case of errorPreviousCalculationToCareTaker memento = calculator.backupLastCalculation();// user enters a numbercalculator.setFirstNumber(17);// user enters a wrong second number and calculates resultcalculator.setSecondNumber(-290);// calculate resultSystem.out.println(calculator.getCalculationResult());// user hits CTRL + Z to undo last operation and see last resultcalculator.restorePreviousCalculation(memento);// result restoredSystem.out.println(calculator.getCalculationResult());}
}
110
-273
110
三. 优缺点
优点:
1. 状态保存与恢复:备忘录模式可以帮助我们保存对象的状态,并在需要时恢复到之前的状态。这在某些情况下非常有用,比如撤销操作或者程序崩溃后的恢复。
2. 封装性和隔离性:可以确保对象的状态保存在备忘录对象中,而不会暴露给其他对象。这为对象的封装性和隔离性提供了保护,使得对象的状态变化对其他对象是透明的。
缺点:
1. 内存占用:可能引起较大的内存占用,特别是当对象的状态较多且状态改变频繁时。每个备忘录对象都需要保存一份完整的状态,如果状态较多或者备忘录对象较多,可能会消耗大量内存。
2. 性能开销:备忘录模式涉及到创建、存储和恢复状态的操作,这些操作可能引起一定的性能开销。特别是在状态较大或者对象较复杂的情况下,备忘录模式的性能可能会受到影响。
JDK中的备忘录模式
java.io.Serializable
相关文章:
设计模式 - 备忘录模式
目录 一. 前言 二. 实现 三. 优缺点 一. 前言 备忘录模式又称快照模式,是一种行为型设计模式。它可以在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要的时候恢复到原先保存的状态。在不违反封装的情况…...
OpenCV4(C++)—— 几何图形的绘制
文章目录 一、基本图形1、线2、线圆3、线椭圆4、矩形 二、多边形 一、基本图形 1、线 绘制线,要给出两个点坐标 void cv::line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness 1, int lineType LINE_8, int shift 0);…...
智能优化算法常用指标一键导出为EXCEL,CEC2017函数集最优值,平均值,标准差,最差值,中位数,秩和检验,箱线图...
声明:对于作者的原创代码,禁止转售倒卖,违者必究! 之前出了一篇关于CEC2005函数集的智能算法指标一键统计,然而后台有很多小伙伴在询问其他函数集该怎么调用。今天采用CEC2017函数集为例,进行展示。 为了突…...
python文件打包方式汇总
在Python中,你可以使用多种方法来打包你的项目,以下是最常见的两种方式: 使用PyInstaller: PyInstaller是一个非常实用的工具,可以将Python程序打包成独立的可执行文件。这样,你就可以在没有Python环境的…...
基于ChatGPT+词向量/词嵌入实现相似商品推荐系统
最近一个项目有个业务场景是相似商品推荐,给一个商品描述(比如 WIENER A/B 7IN 5/LB FZN ),系统给出商品库中最相似的TOP 5种商品,这种单纯的推荐系统用词向量就可以实现,不过,这个项目特点是商品库巨大,有…...
虾皮商品链接获取虾皮商品详情数据(用 Python实现虾皮商品信息抓取)
在网页抓取方面,可以使用 Python、Java 等编程语言编写程序,通过模拟 HTTP 请求,获取虾皮网站上的商品页面。在数据提取方面,可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是,虾皮网站…...
【数据库系统概论】数据查询之单表查询。详细解释WHERE、OEDER BY、GROUP BY 和 HAVING
前言 ❓单表查询选择表中的若干列查询经过计算的值选择表中的若干元组(行)消除取值重复的行查询满足条件的元组(WHERE) 对查询结果排序(ORDER BY)聚集函数对查询结果分组(GROUP BY) …...
2023年医药商业行业发展研究报告
第一章 行业概况 1.1 定义 医药商业行业,作为医药领域的重要组成部分,扮演着至关重要的角色。这一行业专注于医药商品的经营与流通,确保药品能够有效、安全地到达消费者手中。随着医药科技的进步和市场需求的增长,医药商业行业在…...
Android 消息机制
Android 消息机制 Android 的消息机制也是Handler机制,主要作用是用来在不同线程之间通信,通常使用在子线程执行完成一些儿耗时操作,需要回到主线程更新UI时,通过Handler将有关UI操作切换到主线程。由于Android中主线程不可进行耗…...
QT计时器QTime的使用举例
Qt 中的计时器(QTimer)是一种用于执行定时操作的机制。您可以使用 QTimer 来执行周期性任务、在一段时间后执行操作或创建间隔定时器。以下是使用 QTimer 的基本步骤以及一个简单的示例: **包含头文件:**首先,确保您的…...
js中await用法
在JavaScript中,await用于暂停异步函数执行,等待Promise对象的解决。当Promise对象解决时,await将返回被解决的值,否则它将抛出一个被拒绝的Promise错误。 下面是一些使用await的例子: 使用await等待一个Promise对象…...
Qt多工程同名字段自动翻译工具
开发背景 项目里不同工程经常会引用同一批公共类,这些类里如果有字段需要翻译,需要在不同的项目里都翻译一遍,比较麻烦冗余。 特此开发了这个小翻译工具,能读取程序目录下的所有ts文件,以类名归类,不同项目…...
vue3+elementui实现表格样式可配置
后端接口传回的数据格式如下图 需要依靠后端传回的数据控制表格样式 实现代码 <!-- 可视化配置-表格 --> <template><div class"tabulation_main" ref"myDiv"><!-- 尝试过在mounted中使用this.$refs.myDiv.offsetHeight,获取父元素…...
x11截屏源码(ubuntu18.04)
使用x11库实现截屏并保存为png图片 【shot.c】 // filename: shot.c #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/cursorfont.h> #include <png.h> #include <stdio.h> #include <stdlib.h>…...
【ComfyUI】MacBook Pro 安装(Intel 集成显卡)
文章目录 环境概述配置pip镜像配置pip代理git配置(选配)下载comfyUI代码创建、激活虚拟环境下载依赖安装torchvision启动comfyUI为什么Mac不支持CUDA,即英伟达的显卡?安装Intel工具包 环境 显卡:Intel Iris Plus Grap…...
HTTPS 加密全过程
加密协议以前是SSL,现在都是TLS, 而证书现在大多数都是SSL证书 抓包流程: TCP三次握手过后, 客户端发送Client Hello 服务器相应Server Hello 服务器再次响应发送证书: 服务器再发送公钥:...
联邦学习综述二
联邦学习漫画 联邦学习漫画链接: https://federated.withgoogle.com/ Federated Analytics: Collaborative Data Science without Data Collection 博客链接: https://blog.research.google/2020/05/federated-analytics-collaborative-data.html 本篇博客介绍了联邦分析&a…...
Idea本地跑flink任务时,总是重复消费kafka的数据(kafka->mysql)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Idea中执行任务时,没法看到JobManager的错误,以至于我以为是什么特殊的原因导致任务总是反复消费。在close方法中,增加日志,发现jdbc连接被关闭了。 重新…...
基于nodemailer实现邮件发送
概述 node中可用nodemailer实现邮件的发送。本文使用QQ邮箱实现邮件的发送。 实现效果 实现 1. QQ邮箱配置 首先需要开启POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务,如下图所示。 生成授权码 2. 发送邮件 发送邮件的代码比较简单,如下…...
【PostgreSQL内核学习(十八)—— (数据库表参数)】
数据库表参数 default_reloptions 函数案例 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。 本文主要参考了《PostgresSQL数据库内核…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...
Web APIS Day01
1.声明变量const优先 那为什么一开始前面就不能用const呢,接下来看几个例子: 下面这张为什么可以用const呢?因为复杂数据的引用地址没变,数组还是数组,只是添加了个元素,本质没变,所以可以用con…...
