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

Java设计模式—备忘录模式(快照模式)

定义 

        备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,很多软件都提供了撤销(Undo)操作,如 Word、记事本、Photoshop、IDEA等软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态;还有在 浏览器 中的后退键、数据库事务管理中的回滚操作、玩游戏时的中间结果存档功能、数据库与操作系统的备份操作、棋类游戏中的悔棋功能等都属于这类。  

组成结构

备忘录模式的主要角色如下:

发起人(Originator)角色:

记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。

备忘录(Memento)角色:

负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。

管理者(Caretaker)角色:

对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。

备忘录有两个等效的接口:

窄接口:管理者(Caretaker)对象(和其他发起人对象之外的任何对象)看到的是备忘录的窄接口(narror Interface),这个窄接口只允许他把备忘录对象传给其他的对象。
宽接口:与管理者看到的窄接口相反,发起人对象可以看到一个宽接口(wide Interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复这个发起人对象的内部状态。

package debug01;public class debug01 {public static void main(String[] args) {Originator originator = new Originator();CareTaker careTaker = new CareTaker();originator.setState("State #1");originator.setState("State #2");careTaker.add(originator.saveStateToMemento());originator.setState("State #3");careTaker.add(originator.saveStateToMemento());originator.setState("State #4");System.out.println("Current State: " + originator.getState());originator.getStateFromMemento(careTaker.get(0));System.out.println("First saved State: " + originator.getState());originator.getStateFromMemento(careTaker.get(1));System.out.println("Second saved State: " + originator.getState());}
}
  • debug01 类是程序的入口点,其中包含 main 方法。
  • 在 main 方法中,首先创建了 Originator 和 CareTaker 的实例。
  • 然后,originator 对象的状态被设置为 "State #1"、"State #2"、"State #3" 和 "State #4",并且在每次状态更改后,将当前状态保存到 careTaker 中。
  • 最后,打印出最后设置的状态以及通过 careTaker 恢复的两个先前保存的状态。
package debug01;import java.util.*;public class CareTaker {private List<Memento> mementoList = new ArrayList<Memento>();public void add(Memento state) {mementoList.add(state);}public Memento get(int index) {return mementoList.get(index);}
}
  • CareTaker 类负责保存 Originator 的状态。它使用一个 List 来存储 Memento 对象。
  • add 方法用于向 mementoList 中添加状态。
  • get 方法用于获取指定索引位置的 Memento 对象。
package debug01;public class Originator {private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}public Memento saveStateToMemento() {return new Memento(state);}public void getStateFromMemento(Memento memento) {state = memento.getState();}
}
  • Originator 类是原始对象,其中包含了要保存的状态。
  • setState 方法用于设置状态。
  • getState 方法用于获取状态。
  • saveStateToMemento 方法创建并返回一个新的 Memento 对象,该对象包含了当前状态的副本。
  • getStateFromMemento 方法用于从 Memento 对象中恢复状态。

package debug01;
public class Memento {private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}
  • Memento 类用于存储 Originator 的状态。
  • 它有一个带有状态参数的构造函数,用于初始化状态。
  • getState 方法用于获取状态的值。

整个代码实现了备忘录模式,用于保存和恢复对象的状态。

优缺点

优点:

- 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史的状态。
- 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
- 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

缺点:

- 资源消耗大。如果要保存的内部状态信息过多或者特别频繁,将会占用比较大的内存资源。

使用场景

- 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
- 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,idea等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。

相关文章:

Java设计模式—备忘录模式(快照模式)

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

没学数模电可以玩单片机吗?

我们首先来看一下数电模电在单片机中的应用。数电知识在单片机中主要解决各种数字信号的处理、运算&#xff0c;如数制转换、数据运算等。模电知识在单片机中主要解决各种模拟信号的处理问题&#xff0c;如采集光照强度、声音的分贝、温度等模拟信号。而数电、模电的相互转换就…...

FlinkSQL之Flink SQL Join二三事

​ Flink SQL支持对动态表进行复杂而灵活的连接操作。 为了处理不同的场景&#xff0c;需要多种查询语义&#xff0c;因此有几种不同类型的 Join。默认情况下&#xff0c;joins 的顺序是没有优化的。表的 join 顺序是在 FROM 从句指定的。可以通过把更新频率最低的表放在第一个…...

某某消消乐增加步数漏洞分析

一、漏洞简介 1&#xff09; 漏洞所属游戏名及基本介绍&#xff1a;某某消消乐&#xff0c;三消游戏&#xff0c;类似爱消除。 2&#xff09; 漏洞对应游戏版本及平台&#xff1a;某某消消乐Android 1.22.22。 3&#xff09; 漏洞功能&#xff1a;增加游戏步数。 4&#xf…...

SpringBoot动态数据源实现

一、背景 一个应用难免需要连接多个数据库&#xff0c;像我们系统起码连接了5个以上数据库&#xff0c;AWS RDS主库&#xff0c;ECS自搭MySQL从库&#xff0c;工厂系统三个SQLServer数据库&#xff0c;在线网站MySQL数据库&#xff0c;记得很早以前是用SessionFactory配置&…...

计算机网络常见题(持续更新中~)

1 描述一下HTTP和HTTPS的区别 2 Cookie和Session有什么区别 3 如果没有Cookie,Session还能进行身份验证吗&#xff1f; 4 BOI,NIO,AIO分别是什么 5 Netty的线程模型是怎么样的 6 Netty是什么&#xff1f;和Tomcat有什么区别&#xff0c;特点是什么&#xff1f; 7 TCP的三次…...

富格林:可信招数揭发防备暗箱陷阱

富格林悉知&#xff0c;在风云变幻的金融市场中&#xff0c;炒贵金属是一项具有高收益潜力的投资方式。但投资是风险与收益共存的&#xff0c;因此我们在做单投资过程中需总结可信招数揭发暗箱陷阱&#xff0c;防备受害亏损。以下总结几点可信的投资技巧&#xff0c;希望能够帮…...

获取高德安全码SHA1

高德开发者平台上给的三种方法 获取安全码SHA1&#xff0c;这里我自己使用的是第三种方法。 1、通过Eclipse编译器获取SHA1 使用 adt 22 以上版本&#xff0c;可以在 eclipse 中直接查看。 Windows&#xff1a;依次在 eclipse 中打开 Window -> Preferances -> Androi…...

关于RPC

初识RPC RPC VS REST HTTP Dubbo Dubbo 特性&#xff1a; 基于接口动态代理的远程方法调用 Dubbo对开发者屏蔽了底层的调用细节&#xff0c;在实际代码中调用远程服务就像调用一个本地接口类一样方便。这个功能和Fegin很类似&#xff0c;但是Dubbo用起来比Fegin还要简单很多&a…...

pulsar: kafka on pulsar之把pulsar当kafka用

一、下载协议包&#xff08;要和pulsar版本比较一致&#xff09; https://github.com/streamnative/kop/releases?q2.8.0&expandedtrue二、在pulsar的根目录创建一个protocols目录&#xff0c;将上述包放到这个目录里 三、编辑broker.conf(如果是集群)或者standalone.con…...

七月论文审稿GPT第4版:通过paper-review数据集微调Mixtral-8x7b

模型训练 Mixtral-8x7b地址&#xff1a;魔搭社区 GitHub: hiyouga/LLaMA-Factory: Unify Efficient Fine-tuning of 100 LLMs (github.com) 环境配置 git clone https://github.com/hiyouga/LLaMA-Factory.git conda create -n llama_factory python3.10 conda activate lla…...

基于 YOLO V8 Fine-Tuning 训练自定义的目标检测模型

一、YOLO V8 YOLO V8 是由 2023 年 ultralytics 公司开源的发布&#xff0c;是结合了前几代 YOLO 的融合改进版。YOLO V8 支持全方位的视觉 AI 任务&#xff0c;包括检测、分割、姿态估计、跟踪和分类。并且在速度和准确性方面具有无与伦比的性能。能够应用在各种对速度和精度…...

快手,得物,蓝月亮,蓝禾,奇安信,三七互娱,顺丰,康冠科技,金证科技24春招内推

快手&#xff0c;得物&#xff0c;蓝月亮&#xff0c;蓝禾&#xff0c;奇安信&#xff0c;三七互娱&#xff0c;顺丰&#xff0c;康冠科技&#xff0c;金证科技24春招内推 ①得物 【岗位】技术&#xff0c;设计&#xff0c;供应链&#xff0c;风控&#xff0c;产品&#xff0c;…...

全局UI方法-弹窗二-列表选择弹窗(ActionSheet)

1、描述 定义列表弹窗 2、接口 ActionSheet.show(value:{ title: string | Resource, message: string | Resource, autoCancel?: boolean, confrim?: {value: string | Resource, action: () > void }, cancel?: () > void, alignment?: DialogAlignment, …...

Memcached分布式内存对象数据库

一 Memcached 概念 Memcached 是一个高性能的分布式内存对象缓存系统&#xff0c;用于动态 Web 应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数&#xff0c;从而提高动态、数据库驱动网站的速度。 二 在架构中的位置 Memcached 处于前端或中间件后…...

华为广告打包报错,问题思考

华为广告打包时报错 fata日志不一样能反映出完整的错误日志信息&#xff0c;仅看fata日志具有误导性&#xff0c;有可能指向错误的方向。 通过看完整的日志可见&#xff0c;错误的原因为 Caused by: java.lang.ClassNotFoundException: com.huawei.hms.ads.base.R$dimenfata日…...

docker-compose mysql

使用docker-compose 部署 MySQL&#xff08;所有版本通用&#xff09; 一、拉取MySQL镜像 我这里使用的是MySQL8.0.18&#xff0c;可以自行选择需要的版本。 docker pull mysql:8.0.18二、创建挂载目录 mkdir -p /data/mysql8/log mkdir -p /data/mysql8/data mkdir -p /dat…...

PGAdmin 4:用于管理和维护PostgreSQL数据库的强大工具

PGAdmin 4 是一款用于管理和维护PostgreSQL数据库的强大工具。它提供了丰富的功能&#xff0c;帮助数据库管理员和开发人员轻松管理他们的数据库。 下载地址&#xff1a;https://www.pgadmin.org/download/&#xff0c;如常用windows和rpm版本 本地使用&#xff1a;windows …...

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…...

探索数据库--------------mysql主从复制和读写分离

目录 前言 为什么要主从复制&#xff1f; 主从复制谁复制谁&#xff1f; 数据放在什么地方&#xff1f; 一、mysql支持的复制类型 1.1STATEMENT&#xff1a;基于语句的复制 1.2ROW&#xff1a;基于行的复制 1.3MIXED&#xff1a;混合类型的复制 二、主从复制的工作过程 三个重…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...