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

备忘录模式-撤销功能的实现

 在idea写代码的过程中,会经常用到一个快捷键——“crtl + z”,即撤销功能。“备忘录模式”则为撤销功能提供了一个设计方案。

1 备忘录模式

备忘录模式提供一种状态恢复机制。在不破坏封装的前提下,捕获对象内部状态并在该对象之外保存这个状态。可以在以后将对象恢复到原先保存的状态。

图 备忘录UML

Originator:原发器,一个需要保存内部状态的普通类,可以创建一个备忘录,也可通过备忘录来恢复其在某个时候的状态。

Memento:备忘录,存储原发器的内部状态。除了原发器本身及管理者类外,备忘录不能直接供其他类使用。

CareTaker:管理者,负责保存备忘录,但不能对备忘录内容进行操作或检查,无须知道备忘录的细节。

@Data
public class IdeaCodeOriginator {private String code;private Integer position;public IdeaCodeOriginator(String code, Integer position) {this.code = code;this.position = position;}public void restoreMemento(IdeaCodeMemento memento) {this.code = memento.getCode();this.position = memento.getPosition();}public IdeaCodeMemento createMemento() {return new IdeaCodeMemento(code,position);}}@Data
public class IdeaCodeMemento {private String code;private Integer position;public IdeaCodeMemento(String code, Integer position) {this.code = code;this.position = position;}
}public class CareTaker {private final Stack<IdeaCodeMemento> mementoStack = new Stack<>();public IdeaCodeMemento getMemento(int num) {IdeaCodeMemento memento = null;while (num-- > 0 && !mementoStack.isEmpty()) {memento = mementoStack.pop();}return mementoStack.isEmpty() ? memento : mementoStack.pop();}public void saveMemento(IdeaCodeMemento memento) {mementoStack.push(memento);}}public class IdeaCodeEditor {public static void main(String[] args) {CareTaker careTaker = new CareTaker();IdeaCodeOriginator originator1 = new IdeaCodeOriginator("hello", 1);careTaker.saveMemento(originator1.createMemento());IdeaCodeOriginator originator2 = new IdeaCodeOriginator("word", 2);careTaker.saveMemento(originator2.createMemento());IdeaCodeOriginator originator3 = new IdeaCodeOriginator("and", 3);careTaker.saveMemento(originator3.createMemento());IdeaCodeOriginator originator4 = new IdeaCodeOriginator("java", 4);careTaker.saveMemento(originator4.createMemento());//撤回到2步前originator4.restoreMemento(careTaker.getMemento(2));System.out.println(originator4); // IdeaCodeOriginator(code=word, position=2)}}

1.1 优化

1)要避免其他类操作或者检查备忘录的内容。

2)备忘录管理者应该具有通用性。

public interface Memento {
}@Data
public class IdeaCodeOriginator {private String code;private Integer position;public IdeaCodeOriginator(String code, Integer position) {this.code = code;this.position = position;}@Dataprivate static class InnerMemento implements Memento {private String code;private Integer position;public InnerMemento(String code, Integer position) {this.code = code;this.position = position;}}public Memento createMemento() {return new InnerMemento(code,position);}public void restoreMemento(Memento memento) throws Exception {if (memento instanceof InnerMemento) {InnerMemento innerMemento = (InnerMemento) memento;this.code = innerMemento.getCode();this.position = innerMemento.position;} else {throw new Exception("类型错误");}}}public class CareTaker<T> {Stack<T> stack = new Stack<>();public T getMemento(int num) {T memento = null;while (num-- > 0 && !stack.isEmpty()) {memento = stack.pop();}return stack.isEmpty() ? memento : stack.pop();}public void saveMemento(T memento) {stack.push(memento);}}public class IdeaCodeEditor2 {public static void main(String[] args) throws Exception {CareTaker<Memento> objectCareTaker = new CareTaker<>();IdeaCodeOriginator originator1 = new IdeaCodeOriginator("hello", 1);objectCareTaker.saveMemento(originator1.createMemento());IdeaCodeOriginator originator2 = new IdeaCodeOriginator("word", 2);objectCareTaker.saveMemento(originator2.createMemento());IdeaCodeOriginator originator3 = new IdeaCodeOriginator("and", 3);objectCareTaker.saveMemento(originator3.createMemento());IdeaCodeOriginator originator4 = new IdeaCodeOriginator("java", 4);objectCareTaker.saveMemento(originator4.createMemento());originator4.restoreMemento(objectCareTaker.getMemento(3)); // IdeaCodeOriginator(code=hello, position=1)System.out.println(originator4);}}

2 优缺点

如果需要为软件提供撤销功能,备忘录模式无疑是一种很好的解决方案。

优点:1)它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤;

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

3 适用场景

1)保存一个对象在某时刻的全部或部分状态,实现撤销操作。

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

相关文章:

备忘录模式-撤销功能的实现

在idea写代码的过程中&#xff0c;会经常用到一个快捷键——“crtl z”,即撤销功能。“备忘录模式”则为撤销功能提供了一个设计方案。 1 备忘录模式 备忘录模式提供一种状态恢复机制。在不破坏封装的前提下&#xff0c;捕获对象内部状态并在该对象之外保存这个状态。可以在…...

C++入门(二)

文章目录 一、缺省参数1、概念2、缺省参数分类1、全缺省参数2、半缺省参数 3、特性总结 二、函数重载1、引入函数重载2、函数重载概念3、函数重载分类4、C支持函数重载的原理--名字修饰(name Mangling) 三、 引用1、引用概念2、引用特性3、 常引用4、 使用场景1、做参数2、做返…...

【软件设计师】面向对象类图的六种关系

面向对象类图的六种关系&#xff08;继承、实现、依赖、关联、聚合、组合&#xff09; 1、泛化&#xff08;继承&#xff09;2、实现3、依赖4、关联5、聚合6、组合 面向对象类图的六种关系&#xff08;继承、实现、依赖、关联、聚合、组合&#xff09; 进行面向对象设计时&…...

二十七、【四种蒙版】

文章目录 图层蒙版剪贴蒙版快速蒙版矢量蒙版 图层蒙版 在当前图层加上蒙版&#xff0c;黑色画笔的可以让当前图层消失&#xff0c;白色的画笔可以让当前图层出现&#xff1a; 无论填充什么样的颜色&#xff0c;蒙板只有黑白灰三种颜色。模板最简单应用就是我们在插入图形的时候…...

卡尔曼家族从零解剖-(00)目录最新无死角讲解

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解的 卡尔曼家族从零解剖 链接 :卡尔曼家族从零解剖-(00)目录最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/133846882 文末正下方中心提供了本人 联系…...

Linux系统之ip命令的基本使用

Linux系统之ip命令的基本使用 一、ip命令介绍1.1 ip命令简介1.2 ip命令的由来1.3 ip命令的安装包 二、ip命令使用帮助2.1 ip命令的help帮助信息2.2 ip命令使用帮助 三、查看网络信息3.1 显示当前网络接口信息3.2 显示网络设备运行状态3.3 显示详细设备信息3.4 查看路由表3.5 查…...

【推荐算法】ctr cvr联合建模问题合集

ctr和cvr分开建模相比ctcvr的优势&#xff1f; 在电商搜索推荐排序中&#xff0c;将ctr和cvr分开建模&#xff0c;相比直接建模ctcvr的优势是什么&#xff1f; - 萧瑟的回答 - 知乎 总结&#xff1a; 1、ctr的数据可以试试获取&#xff0c;能实时训练。但是cvr存在延迟现象&…...

安装njnx --chatGPT

gpt: 要在 Debian 11 上安装 Nginx&#xff08;通常称为 "nginx"&#xff09;&#xff0c;您可以使用 apt 包管理器执行以下步骤&#xff1a; 1. **登录到您的 Debian 11 服务器**。您可以使用 SSH 客户端以 root 或具有管理员权限的用户身份登录。 2. **更新软件…...

性能测试需求分析

1、客户方提出 客户方能提出明确的性能需求&#xff0c;说明对方很重视性能测试&#xff0c;这样的企业一般是金融、电信、银行、医疗器械等&#xff1b;他们一般对系统的性能要求非常高&#xff0c;对性能也非常了解。提出需求也比较明确。 曾经有一个银行项目&#xff0c;已经…...

logback服务器日志删除原理分析

查看以下的logback官方文档 Chapter 4: Appendershttps://logback.qos.ch/manual/appenders.html 按文档说明&#xff0c;maxHistory是设置保存归档日志的最大数量&#xff0c;该数量的单位受到fileNamePattern里的值%d控制&#xff0c;如果有多个%d,只能有一个主%d&#xff0…...

到底什么才是真正的商业智能(BI)

随着人工智能、云计算、大数据、互联网、物联网等新一代信息化、数字化技术在各行各业内开始大规模的应用&#xff0c;社会上的数字化、信息化程度不断加深&#xff0c;而数据价值也在这样的刺激下成为了个人、机构、企业乃至国家的重要战略资源&#xff0c;成为了继土地、劳动…...

Pulsar Manager配置自定义认证插件访问

Pulsar Manager配置自定义认证插件访问 Pulsar Manager和dashboard部署和启用认证 pulsar自定义认证插件开发 前面博客讲了以token方式访问pulsar 这节博客讲如何配置自定义认证插件的方式访问pulsar #启动pulsar-manager docker run --name pulsar-manager -dit \-p 9527:…...

Java SimpleDateFormat linux时间字符串转时间轴的坑

Mon Oct 16 09:51:28 2023 这是linux 的 date命令得到的时间&#xff0c;要转换称时间戳。 EEE MMM dd HH:mm:ss yyyy 这样的格式&#xff0c;看起来就是正确的&#xff0c;可是就是报错 Unparseable date: "Mon Oct 16 09:51:28 2023" 下面是正确的代码 String[…...

202、RabbitMQ 之 使用 fanout 类型的Exchange 实现 Pub-Sub 消息模型---fanout类型就是广播类型

目录 ★ 使用 fanout 类型的Exchange 实现 Pub-Sub 消息模型代码演示&#xff1a;生产者&#xff1a;producer消费者&#xff1a;Consumer01消费者&#xff1a;Consumer02测试结果 完整代码ConnectionUtilPublisherConsumer01Consumer02pom.xml ★ 使用 fanout 类型的Exchange …...

web 性能优化详解(Lighthouse工具、优化方式、强缓存和协商缓存、代码优化、算法优化)

1.性能优化包含的方面 优化性能概念宽泛&#xff0c;可以从信号、系统、计算机原理、操作系统、网络通信、DNS解析、负载均衡、页面渲染。只要结合一个实际例子讲述清楚即可。 2.什么是性能&#xff1f; Web 性能是客观的衡量标准&#xff0c;是用户对加载时间和运行时的直观…...

docker-compose部署elk(8.9.0)并开启ssl认证

docker部署elk并开启ssl认证 docker-compose部署elk部署所需yml文件 —— docker-compose-elk.yml部署配置elasticsearch和kibana并开启ssl配置基础数据认证配置elasticsearch和kibana开启https访问 配置logstash创建springboot项目进行测试kibana创建视图&#xff0c;查询日志…...

解决java.lang.IllegalArgumentException: servlet映射中的<url pattern>[demo1]无效

当我使用tomcat启动使用servlet项目时&#xff0c;出现了报错&#xff1a; java.lang.IllegalArgumentException: servlet映射中的<url pattern>[demo1]无效 显示路径错误&#xff0c;于是去检查Web.xml中的配置&#xff0c;发现是配置文件的路径写错了&#xff0c;少写了…...

软件测试学习(三)易用性测试、测试文档、软件安全性测试、网站测试

目录 易用性测试 用户界面测试 优秀Ul由什么构成 符合标准和规范 直观 一致 灵活 舒适 正确 实用 为有残疾障碍的人员测试&#xff1a;辅助选项测试 测试文档 软件文档的类型 文档测试的重要性 软件安全性测试 了解黑客的动机 威胁模式分析 网站测试 网页基…...

Java中,对象一定在堆中分配吗?

在我们的日常编程实践中&#xff0c;我们经常会遇到各种类型的对象&#xff0c;比如字符串、列表、自定义类等等。这些对象在内存中是如何存储的呢&#xff1f; 你可能会毫不犹豫地回答&#xff1a;“在堆中&#xff01;”如果你这样回答了&#xff0c;那你大部分情况下是正确…...

AI:38-基于深度学习的抽烟行为检测

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…...

Hadoop 配置 Kerberos 认证

1、安装 Kerberos 服务器和客户端 1.1 规划 服务端&#xff1a; bigdata3 客户端&#xff08;Hadoop集群&#xff09;&#xff1a; bigdata0 bigdata1 bigdata2 192.168.50.7 bigdata0.example.com bigdata0 192.168.50.8 bigdata1.example.com bigdata1 192.168.50.9 b…...

在 Elasticsearch 中实现自动完成功能 2:n-gram

在第一部分中&#xff0c;我们讨论了使用前缀查询&#xff0c;这是一种自动完成的查询时间方法。 在这篇文章中&#xff0c;我们将讨论 n-gram - 一种索引时间方法&#xff0c;它在基本标记化后生成额外的分词&#xff0c;以便我们稍后在查询时能够获得更快的前缀匹配。 但在此…...

美客多、亚马逊卖家如何运用自养账号进行有效测评?

到了10月&#xff0c;卖家朋友们都在忙着准备Q4旺季吧&#xff01; 首先&#xff0c;祝愿所有看到这条推文的卖家朋友&#xff0c;今年旺季都能爆单&#xff0c;赚得盆满钵满&#xff01; 测评是珑哥常谈&#xff0c;一直备受关注&#xff0c;不论是新老卖家都是一个逃不开的…...

MyBatis的缓存,一级缓存,二级缓存

10、MyBatis的缓存 10.1、MyBatis的一级缓存 一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession对象 查询的结果数据会被缓存&#xff0c;下次执行相同的查询语句&#xff0c;就 会从缓存中&#xff08;缓存在内存里&#xff09;直接获取&#xff0c;不会重新访问…...

GitLab(1)——GitLab安装

目录 一、使用设备 二、使用rpm包安装 Gitlab国内清华源下载地址&#xff1a; ①下载命令如下&#xff1a; ②安装命令如下&#xff1a; ③删除rpm包 ④配置 ⑤重载 ⑥重启 ⑦配置自启动 ⑧打开8989端口并重启防火墙 三、GitLab登录 ①访问GitLab的URL ②输入用户…...

退税政策线上VR互动科普展厅为税收工作带来了强大活力

缴税纳税是每个公民应尽的义务和责任&#xff0c;由于很多人缺乏专业的缴税纳税操作专业知识和经验&#xff0c;因此为了提高大家的缴税纳税办事效率和好感度&#xff0c;越来越多地区税务局开始引进VR虚拟现实、web3d开发和多媒体等技术手段&#xff0c;基于线上为广大公民提供…...

centos 7.9离线安装wget

1.下载安装包 登录到wget官网上下载最新的wget的rpm安装包到本地 http://mirrors.163.com/centos/7/os/x86_64/Packages/ 2.上传安装包到服务器 3.安装 rpm -ivh wget-1.14-18.el7_6.1.x86_64.rpm 4.查看版本 wget -V...

【Java学习之道】网络编程的基本概念

引言 这一章我们将一同进入网络编程的世界。在开始学习网络编程之前&#xff0c;我们需要先了解一些基本概念。那么&#xff0c;我们就从“什么是网络编程”这个问题开始吧。 一、网络编程的基本概念 1.1 什么是网络编程 网络编程&#xff0c;顾名思义&#xff0c;就是利用…...

Restful API 设计示例

Restful API 设计示例 一 &#xff0c;HTTP状态码 ✔️正例&#xff1a; 200: 返回成功 说明&#xff1a;200表示成功&#xff0c;4xx表示客户端异常&#xff0c;5xx表示服务端异常&#xff0c;参见HTTP 的返回码含义 ❌反例&#xff1a; 除了200就是500 说明&#xff1…...

为知笔记一个日记模板

<!DOCTYPE HTML><html><head> <meta http-equiv"Content-Type" content"text/html; charsetunicode"> <title>日记&#xff1a;</title><style id"wiz_custom_css">html, .wiz-editor-body {font-siz…...

自助建站平台便宜/百度分析工具

这个问题已经在这里有了答案&#xff1a; > Java Ternary without Assignment 4个如果您编写如下内容&#xff1a;boolean condition;(...)String out condition ? "true" : "false";Syst…...

手机网站的css模板/网站搭建服务

昨天Google I/O开发者大会上宣布&#xff0c;Android Studio 1.0的前瞻版发布了&#xff0c;今早马上下载尝下鲜。 下载地址如下&#xff1a; https://developer.android.com/sdk/installing/studio.html 中文介绍http://www.apkbus.com/android-1844-1.html 很显然的IntelliJ…...

github怎么导入wordpress/提高关键词排名的软文案例

去https://www.virtualbox.org/wiki/Downloads下载Oracle VM VirtualBox Extension Pack安装Oracle VM VirtualBox Extension Pack将启动virtualbox的用户加入vboxusers组中重启电脑启动virtualbox&#xff0c;在设置->USB设备->勾选“启用USB控制器”添加一个筛选器&…...

网站正能量免费下载/免费个人主页网站

1.安装setuptools2.yum install -y mysql-devel python-devel gcc否则会报错&#xff1a;command gcc failed with exit status 13.python setup.py install转载于:https://www.cnblogs.com/biboxie/p/4233422.html...

做网站专业/东莞网站建设最牛

http://jaist.dl.sourceforge.net/sourceforge/pidgin/pidgin-2.3.1.exe转载于:https://blog.51cto.com/axlrose/1294556...

wordpress二级域名设置/传统营销与网络营销的整合方法

spring要与freemarker整合的话&#xff0c;需要两个包&#xff0c;一个是freemarker的jar包&#xff0c;另一个是spring-context-support的jar包。所以我们需要在taotao-item-web工程中确保对这两个jar包的依赖&#xff0c;如下所示。<dependency><groupId>org.spr…...