设计模式——备忘录模式
跟多内容,前往IT-BLOG
备忘录模式(Memento Pattern): 保存对象的某个状态,以便在未来需要的时候进行数据的恢复。相当容易理解,举个简单的例子:Word 软件在编辑时按 Ctrl+Z 组合键时能撤销当前操作,使文档恢复到之前的状态;
一、备忘录模式的基本介绍
【1】备忘录模式(Memento Pattern): 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
【2】现实生活中备忘录是用来记录某些要去做的事情,或者是记录已经达成共同意见的事情,以防忘记。而在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。
【3】备忘录模式属于行为型模式。
【4】实现了信息的封装,使得用户不需要关心状态和保存细节。符合 “单一职责原则” 。
【5】为了节约内存,备忘录模式可以和原型模式配合使用。
二、备忘录模式的结构与类图
忘录模式的核心是设计备忘录类以及用于管理备忘录的管理者类,备忘录模式的主要角色如下:
【1】发起人(Originator)角色: 记录当前对象的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
【2】备忘录(Memetor)角色: 负责存储发起人对象的内部状态,在需要的时候提供这些内部状态给发起人。
【3】管理者(Caretaker)角色: 对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
三、备忘录模式案例分析
我们使用备忘录模式写一个学校 100 米考试的案例:5 人一组,进行分组测试。我们需要备份的对象是,一组学生的成绩。
【1】发起人(Originator)角色: 发起人需要依赖备忘录类,对自己每次记录的成绩进行备份 createMemento 。同时需要提供一个还原方法 getOriginalFromMemento 将需要的备份类作为参数传递进来,并将结果赋值给目标类。
//100 米 测试 5人一组 ,这是个人所花费的时间,我们使用备忘录的方式实现一下。
public class Original {//姓名private String name;//时间private int timestamp;public Memento createMemento() {return new Memento(name, timestamp);}//获取目标对象 通过排名public void getOriginalFromMemento(Memento memento) {name = memento.getName();timestamp = memento.getTimestamp();}public int getTimestamp() {return timestamp;}public void setTimestamp(int timestamp) {this.timestamp = timestamp;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Original [name=" + name + ", timestamp=" + timestamp + "]";}
}
【2】备忘录(Memetor)角色: 提供一些目标对象需要备份的属性,通过构造器进行属性传递。
public class Memento {//姓名private String name;//时间private int timestamp;//构造器public Memento(String name, int timestamp) {super();this.name = name;this.timestamp = timestamp;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getTimestamp() {return timestamp;}public void setTimestamp(int timestamp) {this.timestamp = timestamp;}
}
【3】管理者(Caretaker)角色: 创建一个存储备忘录对象的集合 <Map、List、Set>
等,同时创建添加、获取、清空等方法。
public class Caretaker {//排名private int index = 1;//用于顺序存储 参加测试的 十名同学的成绩Map<Integer, Memento> mementos = new HashMap<Integer, Memento>();//提供一个 add 方法public void add(Memento m) {mementos.put(index, m);index += 1;}//获取备份类public Memento get(int key) {return mementos.get(key);}//归位public void remove() {mementos.clear();}
}
【4】客户端(Client)角色: 首先将顺序按的前五名同学的成绩及姓名,通过集合 Map 按照名次存储。五名同学测试完成后,通过目标类的 getOriginalFromMemento 方法,根据名次获取同学的成绩,并记录在成绩花名册中。最后,清空记录下一组。
public class Client {public static void main(String[] args) {//创建 目标类Original original = new Original();//管理类Caretaker managerMemento = new Caretaker();//记录成绩recordResults(original,managerMemento);//获取第一名的成绩System.out.println("恢复前目标类的记录值"+original.toString());//从集合中获取第一名的值Memento memento1 = managerMemento.get(1);//调用目标类的还原方法original.getOriginalFromMemento(memento1);System.out.println("恢复第一名的成绩信息:"+original.toString());//从集合中获取第三名的值Memento memento3 = managerMemento.get(3);//调用目标类的还原方法original.getOriginalFromMemento(memento3);System.out.println("恢复第三名的成绩信息:"+original.toString());//清空记录下一组managerMemento.remove();}private static void recordResults(Original original,Caretaker managerMemento) {//第一名学生成绩original.setName("张三");original.setTimestamp(2330);//创建一个备份类Memento memento1 = original.createMemento();//备份类存入 管理类中managerMemento.add(memento1);//第二名学生成绩original.setName("李四");original.setTimestamp(2550);//创建一个备份类Memento memento2 = original.createMemento();//备份类存入 管理类中managerMemento.add(memento2);//第三名学生成绩original.setName("王五");original.setTimestamp(2560);//创建一个备份类Memento memento3 = original.createMemento();//备份类存入 管理类中managerMemento.add(memento3);}
}
【5】结果展示: 备份者模式思想相对简单,主要查看细节上的实现。备份类相对简单,就一个普通类。但是目标类,提供了存储原始对象和获取原始对象的方法,是备份者模式的精华所在。
恢复目标类的记录值Original [name=王五, timestamp=2560]
恢复第一名的成绩信息:Original [name=张三, timestamp=2330]
恢复第三名的成绩信息:Original [name=王五, timestamp=2560]
相关文章:

设计模式——备忘录模式
跟多内容,前往IT-BLOG 备忘录模式(Memento Pattern): 保存对象的某个状态,以便在未来需要的时候进行数据的恢复。相当容易理解,举个简单的例子:Word 软件在编辑时按 CtrlZ 组合键时能撤销当…...
深入理解Django与Redis的集成实践
在现代的Web开发中,高效的数据存取和缓存策略是提升应用性能的关键。Django作为一个广泛使用的Python Web框架,提供了丰富的功能以支持高效的Web应用开发。而Redis,作为一个高性能的键值存储系统,常被用于缓存、会话管理等多种场景…...

Java设计模式 – 四大类型
设计模式 – 四大类型 创建型模式结构型模式行为型模式J2EE模式 设计模式(Design pattern)是重构解决方案 根据书Design Patterns – Elements of Reusable Object-Oriented Software(中文译名:设计模式 – 可复用的面向对象软件元…...

查看阿里云maven仓中某个库有哪些版本
起因 最近项目上有做视频业务,方案是使用阿里云的短视频服务,其中也有使用到阿里云的上传SDK,过程中有遇一个上传SDK的内部崩溃,崩溃栈如下: Back traces starts. java.lang.NullPointerException: Attempt to invok…...

【通信系统】MIMO阵列信号来向DOA估计实现~含FOCUSS、OMP、贝叶斯学习(SBL)等稀疏重构法和常规、子空间法、空间平滑滤波法
MIMO阵列目标信号来向估计原理与实现~基于常规法、子空间变换法和稀疏恢复法 写在最前前言空间谱估计的历史发展 仿真原理离散时间阵列信号模型波束形成矩阵(完备字典)回波生成空间平滑滤波传统方法CBF~常规波束成型Capon~最小方差无失真响应法ML~最大似然估计法 子空间方法MUS…...

高级变量赋值和变量的间接引用
1.高级变量赋值 var${str-lucky} 变量配置方式 var${str:-lucky} 变量配置方式 var${strlucky} 变量配置方式 2.变量的间接引用 eval 命令 eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,该命令对变…...

vue动态修改侧边菜单栏宽度
1.添加可修改宽度的dom元素 <div style"background: #f5f7fa;padding: 20px 10px;"><label>菜单宽度 </label><el-input v-model"sideWidth" placeholder"请输入宽度值" style"width: 100px"/> px<el-but…...

【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]
阅读导航 引言一、C语言的输入与输出二、流是什么三、CIO流1. C标准IO流(1)istream(2)ostream(3)iostream(4)cin 和 cout 2. C文件IO流(1)ifstream࿰…...
【Spark系列5】Dataframe下常用算子API
Apache Spark DataFrame API 提供了丰富的方法来处理分布式数据集。以下是一些常见的 DataFrame API 类别和方法,但这不是一个完整的列表,因为 API 非常广泛。这些方法可以分为几个主要类别: 转换操作(Transformations࿰…...

【大数据】Flink SQL 语法篇(二):WITH、SELECT WHERE、SELECT DISTINCT
Flink SQL 语法篇(二) 1.WITH 子句2.SELECT & WHERE 子句3.SELECT DISTINCT 子句 1.WITH 子句 应用场景(支持 Batch / Streaming):With 语句和离线 Hive SQL With 语句一样的,语法糖 1,使用…...
leetcode-链表专题
25.K个一组翻转链表 题目链接 25. K 个一组翻转链表 - 力扣(LeetCode) 解题思路 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class So…...

Vue打包Webpack源码及物理路径泄漏问题解决
修复前: 找到vue.config.js文件,在其中增加配置 module.exports {productionSourceMap: false,// webpack 配置configureWebpack: {devtool: false,}}其中打包的物理路径泄露我这边试了好多次,发现只有打包的时候NODE_ENVproduction 才能保…...

MySQL学习记录——일 MySQL 安装、配置
文章目录 1、卸载内置环境2、安装MySQL3、启动4、登录5、配置my.cnf 当前环境是1核2G云服务器,CentOS7.6。要在root用户下进行操作 1、卸载内置环境 云服务器中有可能会自带mysql还有mariadb这样的数据库服务,在安装我们mysql前,得先查找一下…...

获取真实 IP 地址(二):绕过 CDN(附链接)
一、DNS历史解析记录 DNS 历史解析记录指的是一个域名在过去的某个时间点上的DNS解析信息记录。这些记录包含了该域名过去使用的IP地址、MX记录(邮件服务器)、CNAME记录(别名记录)等 DNS 信息。DNS 历史记录对于网络管理员、安全研…...

正则表达式补充以及sed
正则表达式: 下划线算 在单词里面 解释一下过程: 在第二行hello world当中,hello中的h 与后面第一个h相匹配,所以hello中的ello可以和abcde匹配 在world中,w先匹配h匹配不上,则在看0,r&#…...
LLM智能体开发指南
除非你一直生活在岩石下,否则你一定听说过像 Auto-GPT 和 MetaGPT 这样的项目。 这些是社区为使 GPT-4 完全自治而做出的尝试。在其最原始的形式中,代理基本上是文本到任务。你输入一个任务描述,比如“给我做一个贪吃蛇游戏”,并使…...

基于springboot校园二手书交易管理系统源码和论文
在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括乐校园二手书交易管理系统的网络应用,在外国二手书交易管理系统已经是很普遍的方式,不过国内的管理系统可能还处于起步阶段。乐校园二手书交易管理系统…...

Oracle和Mysql数据库
数据库 Oracle 体系结构与基本概念体系结构基本概念表空间(users)和数据文件段、区、块Oracle数据库的基本元素 Oracle数据库启动和关闭Oracle数据库启动Oracle数据库关闭 Sqlplussqlplus 登录数据库管理系统使用sqlplus登录Oracle数据库远程登录解锁用户修改用户密码查看当前语…...
java学习笔记:java常见注解语句汇总、解析及应用
文章目录 一、什么是注解二、注解有什么作用三、常见的Java注解及其功能介绍和示例OverrideDeprecatedSuppressWarningsFunctionalInterfaceSafeVarargsSuppressWarnings 一、什么是注解 Java中所有以开头的语句被称为注解(Annotation)。 注解是一种元数…...

k8s Sidecar filebeat 收集容器中的trace日志和app日志
目录 一、背景 二、设计 三、具体实现 Filebeat配置 K8S SideCar yaml Logstash配置 一、背景 将容器中服务的trace日志和应用日志收集到KAFKA,需要注意的是 trace 日志和app 日志需要存放在同一个KAFKA两个不同的topic中。分别为APP_TOPIC和TRACE_TOPIC 二、…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...