【设计模式】行为型设计模式之 备忘录模式(快照模式)

介绍

备忘录应用场景明确并且有限,一般用来数据的防丢失、撤销和恢复。对大对象的备份和恢复,备忘录模式能有效的节省时间和空间开销。

定义

备忘录模式:也称为快照模式,在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态以便后续能将这个对象恢复成之前的状态。
备忘录模式的两个要点

  1. 存储副本以便后期恢复
  2. 要在不违反封装原则的前提下恢复

备忘录模式中的角色

  1. 原发器(Originator):负责创建一个备忘录,用以存储其当前状态;同时也可以利用备忘录恢复其内部状态
  2. 备忘录(Memento):用于存储原发器对象的内部状态。为了保护原发器对象的封装性,备忘录对象通常被设计为不可直接访问其内容,只暴露给原发器。
  3. 负责人(Caretaker):负责保管备忘录对象,但不直接读取或修改备忘录的内容。它只是简单的提供一个存储空间,用来在需要的时候传递给原发器。

使用记事本程序来理解各个角色

  1. 记事本本身为原发器,可以创建备份、从备份恢复
  2. 记事本备份为 Memento 备忘录,由原发器创建
  3. 保存所有记事本备份的对象则为负责人,保存所有的记事本备份。

代码示例

未使用备忘录模式实现输入备份

/*** 简单的文本编辑器** @author Jean* @date 2024/06/07*/
class InputText {private StringBuilder text = new StringBuilder();public String getText() {return text.toString();}public void append(String input) {text.append(input);}public void setText(String text) {this.text.replace(0, this.text.length(), text);}
}/*** 保存并处理快照** @author Jean* @date 2024/06/07*/
public class SnapshotHolder {private Stack<InputText> snapshots = new Stack<>();public InputText popSnapshot() {return snapshots.pop();}public void pushSnapshot(InputText inputText) {InputText deepClonedInputText = new InputText();deepClonedInputText.setText(inputText.getText());snapshots.push(deepClonedInputText);}}

问题:

  1. 为了能尽快恢复快照使用了 setText ,可能导致被其他业务误用,方法违背了封装原则。
  2. 快照本身应该是不可变的,不应该包含任何修改内部状态的函数,但是上述实现直接复用 InputText 的定义,也违反了快照的封装原则。

使用备忘录模式实现输入备份

    //定义一个文本编辑器,能保存编辑的文本//原发器(Originator) 负责创建一个备忘录,用以存储其当前状态;同时也可以利用备忘录恢复其内部状态。class InputText{private StringBuilder text = new StringBuilder();public String getText(){return text.toString();}public void append(String input){text.append(input);}}//备忘录角色//用于存储原发器对象的内部状态。为了保护原发器对象的封装性,备忘录对象通常被设计为不可直接访问其内容,只暴露给原发器。class SnapShot{private String text;public SnapShot(String text) {this.text = text;}public String getText() {return text;}}//负责人 caretaker//负责保管备忘录对象,但不直接读取或修改备忘录的内容。它只是简单的提供一个存储空间,用来在需要的时候传递给原发器。public class SnapshotHolder{private Stack<SnapShot> snapShots=new Stack<>();public SnapShot popSnapshot(){return snapShots.pop();}public void PushSnapshot(SnapShot snapShot){snapShots.push(snapShot);}}

总结

备忘录模式适合的场景如下:

  • 当需要实现撤销/重做功能时。
  • 当需要保存和恢复对象的内部状态,但又不想暴露这些状态的细节时。
  • 在某些性能非关键路径上,可以接受因保存状态而带来的资源消耗。

备忘录模式在实现时,设计者需要权衡状态保存的频率和成本,以确保不会因为过度使用而导致资源紧张。此外,也可以考虑对备忘录进行优化,比如限制保存的状态数量,或者采用更为高效的序列化技术来减少存储开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/345602.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【qt】启动窗口的玩法

启动窗口的玩法 一.应用场景二.界面类设计窗口三.main中创建四.窗口显示标识五.功能实现1.读取注册表2.md5加密3.登录实现4.保存注册表5.功能演示 六.鼠标事件拖动窗口1.找到鼠标事件的函数2.点击事件3.移动事件4.释放事件 七.总结 一.应用场景 一般我们的软件和应用都会一个登…

线性代数|机器学习-P11方程Ax=b求解研究

文章目录 1. 变量数和约束条件数大小分类2. 最小二乘法和Gram-schmidt变换2.1 Gram-schmidt变换2.2 最小二乘法2.2.1 损失函数-Lasso 和regression2.2.2 损失函数-Lasso2.2.3 损失函数-regression2.2.4 Regression岭回归-矩阵验证2.2.5 Regression岭回归-导数验证 3. 迭代和随机…

CS1061 “HtmlHelper”未包含“Partial”的定义,并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1061 “HtmlHelper”未包含“Partial”的定义&#xff0c;并且找不到可接受第一个“HtmlHelper”类型参数的可访问扩展方法“Partial”(是否缺少 using 指令或程序集引用?) 14_Views_Message_E…

【车载开发系列】MCU选型

【车载开发系列】MCU选型 【车载开发系列】MCU选型 【车载开发系列】MCU选型一. 重要概念二. MCU选型的风险风险1风险2 三. MCU选型要点四. MCU选型维度五. MCU 选型需要考虑的因素1&#xff09;ROM/RAM2&#xff09;速度/主频3&#xff09;分析外设需求4&#xff09;工作电压(…

算法家族之一——二分法

目录 算法算法的打印效果如果算法里的整型“i”为1如果算法里的整型“i”为11 算法的流程图算法的实际应用总结 大家好&#xff0c;我叫 这是我58&#xff0c;现在&#xff0c;请看下面的算法。 算法 #define _CRT_SECURE_NO_WARNINGS 1//<--预处理指令 #include <stdi…

html--万年历

<!DOCTYPE html> <html lang"zh_CN"><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /><meta charset"utf-8" /><title>万年历</title><link rel"styles…

压力测试-性能指标-Jmeter使用-压力测试报告

文章目录 1.压测目的2.性能指标3.Jmeter3.1Jmeter使用3.1.1 运行Jmeter3.1.2 添加线程组3.1.3设置HTTP请求3.1.4 设置监视器 3.2 查看Jmeter压测结果3.2.1 查看结果树3.2.2 查看汇总报告3.2.3 查看聚合报告3.2.4 查看汇总图 1.压测目的 内存泄漏&#xff1a;OOM&#xff0c;重…

Llama模型家族之Stanford NLP ReFT源代码探索 (四)Pyvene论文学习

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

【嵌入式】波特率9600,发送8个字节需要多少时间,如何计算?

问题&#xff1a; 波特率9600&#xff0c;发送 01 03 00 00 00 04 44 09 (8字节) 需要多少时间&#xff0c;如何计算&#xff1f; 在计算发送数据的时间时&#xff0c;首先要考虑波特率以及每个字符的数据格式。对于波特率9600和标准的UART数据格式&#xff08;1个起始位&…

彩虹易支付最新版源码

源码简介 彩虹易支付最新版源码&#xff0c;更新时间为5.1号 2024/05/01&#xff1a; 1.更换全新的手机版支付页面风格 2.聚合收款码支持填写备注 3.后台支付统计新增利润、代付统计 4.删除结算记录支持直接退回商户金额 安装环境 1.PHP版本>7.4 2.Mysql数据库 安装教…

C++ Qt实现http url启动本地应用程序

更多Qt文章,请访问《深入浅出C++ Qt开发技术专栏》:https://blog.csdn.net/yao_hou/category_9276099.html 文章目录 1、注册自定义协议2、编写web页面3、编写C++应用程序我们在使用腾讯会议时经常会通过http链接打开本地的腾讯会议,例如下图: 打开会议发起人给的链接,会出…

⾃动化批量管理-Ansible

目录 一、ansible 简介 自动化工具选择 &#xff08;了解&#xff09;​编辑 1、ansible 是什么&#xff1f; 2、ansible 特点 3、ansible 架构图 二、ansible 任务执行 1、ansible 任务执行模式 2、ansible 执行流程 3、ansible 命令执行过程 三、ansible 配置详解 …

【iOS】UI学习——登陆界面案例、照片墙案例

文章目录 登陆界面案例照片墙案例 登陆界面案例 这里通过一个登陆界面来复习一下前面学习的内容。 先在接口部分定义两个UILabel、两个UITextField、两个UIButton按键&#xff1a; #import <UIKit/UIKit.h>interface ViewController : UIViewController {UILabel* _lb…

基于AT89C51单片机的红外防盗报警器设计

第一章 绪论1.1 选题背景 随着社会科学的不断进步和发展,人们生活水平得到很大的提高,对个人私有财产的保护越来越重视,因而对于防盗的措施提出了更高的要求。本设计就是为了满足现代生活防盗的需要而设计的应用于家庭、车库、仓库和保险柜等处进行防盗监控的无线防盗报警装…

【RAG入门教程03】Langchian框架-文档加载

Langchain 使用文档加载器从各种来源获取信息并准备处理。这些加载器充当数据连接器&#xff0c;获取信息并将其转换为 Langchain 可以理解的格式。 LangChain 中有几十个文档加载器&#xff0c;可以在这查看https://python.langchain.com/v0.2/docs/integrations/document_lo…

Hive日志介绍

日志描述 日志路径&#xff1a;Hive相关日志的默认存储路径为“/var/log/Bigdata/hive/角色名”&#xff0c;Hive1相关日志的默认存储路径为“/var/log/Bigdata/hive1/角色名”&#xff0c;以此类推。 HiveServer&#xff1a;“/var/log/Bigdata/hive/hiveserver”&#xff0…

【算法】常用排序算法(插入排序、希尔排序、堆排序、选择排序、冒泡排序、快速排序、归并排序、计数排序)超详细

排序算法是数据结构相关知识中非常重要的一节&#xff0c;相信很多小伙伴对这部分知识一知半解。那么接下来&#xff0c;小编就要带领大家一起来进行对排序算法的深入剖析学习&#xff0c;希望本篇文章能够使你有所收获&#xff01; 一.常见的排序算法 排序算法有很多种&#…

‘AndroidStudio工具平台’尝试运行‘Android原生项目’

AndroidStudio工具平台 (内嵌Intelli IDEA集成环境) /Users/haijunyan/Library/Android/sdk 配置环境变量: #adb命令&#xff0c;安装APK查看连接设备 platform-tools #emulator命令&#xff0c;通过命令创建模拟器 tools #用NDK框架搭建的项目&#xff0c;用到下面的命令编译 …

【Oracle】Oracle导入导出dmp文件

文章目录 前言一、什么是dmp&#xff1f;二、imp/impdp、exp/expdp对比及示例1.区别2.imp/impdp对比及示例a. impb. impbp 3.exp/expdp对比及示例a. expb.expdp 3.其他事项 三、执行导入导出前置条件1.创建角色并授权2.创建目录映射 前言 在工作中&#xff0c;经常会遇到需要备…

Serif Affinity 2.5 (macOS, Windows) - 专业创意软件

Serif Affinity 2.5 (macOS, Windows) - 专业创意软件 Affinity Designer 2, Affinity Photo 2, Affinity Publisher 2 请访问原文链接&#xff1a;Serif Affinity 2.5 (macOS, Windows) - 专业创意软件&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主…