备忘录模式的理解和实践

引言

        在软件开发中,我们经常会遇到需要保存对象状态并在某个时间点恢复到该状态的需求。这种需求类似于我们平时说的“后悔药”,即允许用户撤销之前的操作,恢复到某个之前的状态。备忘录模式(Memento Pattern)正是为了解决这类问题而诞生的设计模式之一。本文将详细讲解备忘录模式的概念、原理及其在Java中的实践应用。

 

一、备忘录模式概述

1.1 定义

        备忘录模式是一种行为设计模式,用于在不暴露对象实现细节的情况下,捕获并保存对象的内部状态,以便以后可以将对象恢复到这个状态。该模式的主要目的是允许用户恢复到对象之前的状态,从而提供某种形式的撤销功能。

1.2 结构

        备忘录模式包含三个主要角色:

  • 发起人(Originator):创建并恢复备忘录的对象。
  • 备忘录(Memento):存储发起人内部状态的快照,并且防止其他对象访问备忘录。备忘录通常只有发起人可以访问其内容。
  • 管理者(Caretaker):负责保存和恢复备忘录,但不能检查或操作备忘录的内容。

1.3 原理

  1. 创建备忘录:发起人通过调用自身的方法创建当前状态的备忘录。
  2. 保存备忘录:管理者接收并保存发起人创建的备忘录。
  3. 恢复状态:发起人通过管理者获取之前保存的备忘录,并恢复到该状态。

二、备忘录模式的优点和缺点

2.1 优点

  • 提供了撤销功能:用户可以通过恢复备忘录来撤销之前的操作。
  • 封装性强:备忘录对象只由发起人创建和解释,外部对象无法直接访问其内容,增强了封装性。
  • 易于实现:备忘录模式相对简单,易于理解和实现。

2.2 缺点

  • 资源开销:保存多个备忘录对象会占用较多的内存资源。
  • 实现复杂:在复杂系统中,创建和恢复备忘录可能需要较多的代码,增加了系统的复杂性。

三、备忘录模式的实践

        下面我们以一个简单的文本编辑器为例,演示如何使用备忘录模式实现撤销功能。

3.1 发起人(Originator)

// 发起人接口
public interface Originator {void setState(String state);String getState();Memento createMemento();void setMemento(Memento memento);
}// 具体的发起人类
public class TextEditor implements Originator {private String content;@Overridepublic void setState(String state) {this.content = state;}@Overridepublic String getState() {return this.content;}@Overridepublic Memento createMemento() {return new TextMemento(content);}@Overridepublic void setMemento(Memento memento) {if (memento instanceof TextMemento) {this.content = ((TextMemento) memento).getContent();}}
}


3.2 备忘录(Memento)

// 备忘录接口
public interface Memento {
}// 具体的备忘录类
public class TextMemento implements Memento {private String content;public TextMemento(String content) {this.content = content;}public String getContent() {return content;}
}


3.3 管理者(Caretaker)

import java.util.ArrayList;
import java.util.List;// 管理者类
public class Caretaker {private List<Memento> mementoList = new ArrayList<>();public void add(Memento memento) {mementoList.add(memento);}public Memento get(int index) {return mementoList.get(index);}
}


3.4 客户端代码

public class Client {public static void main(String[] args) {TextEditor editor = new TextEditor();Caretaker caretaker = new Caretaker();editor.setState("First state");caretaker.add(editor.createMemento());editor.setState("Second state");caretaker.add(editor.createMemento());editor.setState("Third state");// 回滚到第二个状态System.out.println("Current State: " + editor.getState());editor.setMemento(caretaker.get(1));System.out.println("Rollback to State: " + editor.getState());// 回滚到第一个状态editor.setMemento(caretaker.get(0));System.out.println("Rollback to State: " + editor.getState());}
}


3.5 运行结果

Current State: Third state
Rollback to State: Second state
Rollback to State: First state


四、备忘录模式的应用场景

备忘录模式在实际开发中有很多应用场景,以下是一些常见的例子:

  • 文本编辑器:撤销和重做功能。
  • 数据库事务:保存事务开始前的状态,以便在事务失败时回滚。
  • 游戏开发:保存游戏进度,允许玩家在失败时重新开始。
  • 绘图软件:撤销和重做绘图操作。

总结

        备忘录模式是一种强大的设计模式,用于在不暴露对象内部实现细节的情况下保存和恢复对象的状态。通过引入备忘录对象,我们可以在需要时恢复到对象之前的状态,从而实现撤销功能。虽然备忘录模式在资源开销和实现复杂度上有一些缺点,但在许多应用场景中,它仍然是一种非常有效的解决方案。

        希望本文能帮助你理解备忘录模式,并通过具体的Java代码示例掌握其实现方法。如果你在实际开发中遇到需要撤销功能的需求,不妨尝试一下备忘录模式,相信它会给你的项目带来很大的帮助。

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

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

相关文章

湖南铂乐家具新潮流,岛台不再是大平层的专属

湖南铂乐家具设计师们以巧思打破常规&#xff0c;无论是精致温馨的小户型公寓&#xff0c;还是布局紧凑的普通住宅&#xff0c;都能找到适配的岛台设计。以往岛台总是与宽敞开阔的大平层空间紧密相连&#xff0c;仿佛是大户型的身份象征。而如今岛台不再是大平层的专属。 在固…

RK3568笔记3:开发板启动流程

第1章 启动流程 1.1 上电复位 CPU 复位&#xff0c;进入启动模式。系统硬件查找启动设备&#xff08;如 eMMC&#xff09;。 1.2 ROM Code 阶段&#xff08;硬件引导&#xff09; 在片上 ROM 中存储的启动代码&#xff08;BootROM&#xff09;运行。ROM Code 从 eMMC 的 Boo…

重邮+数字信号处理实验三:z变换及离散LTI系统的z域分析

实验目的&#xff1a; &#xff08; 1 &#xff09;学会运用 Matlab 求离散时间信号的有理函数 z 变换的部分分式展开&#xff1b; &#xff08; 2 &#xff09;学会运用 Matlab 分析离散时间系统的系统函数的零极点&#xff1b; &#xff08; 3 &#xff09;学会运用 …

dolphinScheduler 任务调度

#Using docker-compose to Start Server #下载&#xff1a;https://dlcdn.apache.org/dolphinscheduler/3.1.9/apache-dolphinscheduler-3.1.9-src.tar.gz $ DOLPHINSCHEDULER_VERSION3.1.9 $ tar -zxf apache-dolphinscheduler-"${DOLPHINSCHEDULER_VERSION}"-src.t…

node.js中跨域请求有几种实现方法

默认情况下&#xff0c;出于安全考虑&#xff0c;浏览器会实施同源策略&#xff0c;阻止网页向不同源的服务器发送请求或接收来自不同源的响应。 同源策略&#xff1a;协议、域名、端口三者必须保持一致 <!DOCTYPE html> <html lang"en"> <head>&l…

【机器学习】机器学习的基本分类-监督学习-决策树(Decision Tree)

决策树是一种树形结构的机器学习模型&#xff0c;适用于分类和回归任务。它通过一系列基于特征的条件判断来将数据分割为多个子区域&#xff0c;从而预测目标变量的值。 1. 决策树的结构 根节点&#xff08;Root Node&#xff09; 决策树的起点&#xff0c;包含所有样本。根据某…

支付宝租赁小程序助力便捷生活新方式

内容概要 支付宝租赁小程序为现代人带来了许多惊喜&#xff0c;它不仅仅是一个简单的租赁平台&#xff0c;更是生活中不可或缺的好帮手。想象一下&#xff0c;无论你缺少什么&#xff0c;从工具到家居用品&#xff0c;只需轻轻一点&#xff0c;便能轻松找到需要的物品。这个小…

搭建高可用负载均衡系统:Nginx 与云服务的最佳实践

搭建高可用负载均衡系统&#xff1a;Nginx 与云服务的最佳实践 引言 在项目开发过程中&#xff0c;我们通常在开发和测试阶段采用单机架构进行开发和测试。这是因为在这个阶段&#xff0c;系统的主要目的是功能实现和验证&#xff0c;单机架构足以满足开发人员的日常需求&…

2024年12月5日Github流行趋势

项目名称&#xff1a;HelloGitHub 项目维护者&#xff1a;521xueweihan, yaowenqiang, daixiang0等项目介绍&#xff1a;分享 GitHub 上有趣、入门级的开源项目。项目star数&#xff1a;95,244项目fork数&#xff1a;9,707 项目名称&#xff1a;Best-websites-a-programmer-sh…

乾元通渠道商中标福州市人防信息化建设项目

乾元通渠道商中标福州市人防信息化建设项目&#xff0c;乾元通作为应急通讯设备厂家&#xff0c;为项目提供车载版多链路聚合通信保障设备 QYT-X1s。 青岛乾元通数码科技有限公司作为国家应急产业企业&#xff0c;深耕于数据调度算法研究&#xff0c;参与了多项国家及省部级信息…

unity3d—demo(实现给出图集名字和图片名字生成对应的图片)

目录 实现给出图集名字和图片名字生成对应的图片&#xff1a; 代码示例&#xff1a; dic: 键 是图集名称 值是一个字典 该字典键是图片名称 值是图片&#xff0c;结构如图&#xff1a; 测试代码&#xff1a; 结果&#xff1a; SpriteRenderer 讲解&#xff1a; Resour…

小型商贸公司用什么进销存软件?

最近&#xff0c;一个商贸公司的客户在了解产品时&#xff0c;向我们倾诉了自己的烦恼&#xff1a;“因为公司规模比较小&#xff0c;所以没有使用专业的进销存软件来进行管理&#xff0c;平时记录数据什么的也是使用比较简单的Excel表格。但是&#xff0c;随着业务的扩大&…

学习SqlSugar调用达梦数据库的存储过程的基本用法

将之前学习达梦数据库递归用法的SQL语句封装为存储过程&#xff0c;然后使用SqlSugar在C#程序中调用。   打开达梦管理工具&#xff0c;在SCHOOL数据库的存储过程文件夹新建存储过程&#xff0c;这里需注意&#xff0c;存储过程名称及参数名称都需要大写&#xff0c;且参数名…

记录一次老平台改造通知用户刷新页面,纯前端实现

记录一次老平台改造通知用户刷新页面&#xff0c;纯前端实现 方案概述背景现状问题本质 方案设计前提设计实现 其他补充写在最后的话抛出一个问题 方案概述 背景 前端构建完上线&#xff0c;用户还停留还在老页面&#xff0c;用户不知道网页重新部署了&#xff0c;跳转页面的时…

【WRF理论第十三期】详细介绍 Registry 的作用、结构和内容

目录 1. Introduction&#xff1a;介绍 Registry 的作用和功能。2. Registry Contents&#xff1a;详细描述 Registry 的结构和内容&#xff0c;包括各个部分的条目类型。2.1. DIMSPEC ENTRIES&#xff08;维度规格条目&#xff09;2.2. STATE ENTRIES&#xff08;状态变量条目…

微信小程序提交测试版,但是扫描体验版的二维码 显示 页面不存在

检查路径首页是否和我们微信小程序中的首页路径一致。 显然我的不一致。 {"pagePath": "pages/index/index","text": "产品","iconPath": "icons/Group 450.png","selectedIconPath": "/icons/组 …

GitToolBox插件:让IntelliJ IDEA的Git操作如虎添翼

GitToolBox插件介绍 GitToolBox是一款针对IntelliJ IDEA的插件&#xff0c;旨在增强IDE内置的Git功能&#xff0c;使Git操作更加便捷和高效。无论是单独开发者还是团队中的一员&#xff0c;这个插件都能帮助更好地管理代码和协作流程。 功能特点 分支管理&#xff1a;GitToolBo…

聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程

聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程 系统采用FastAdmin框架独立全新开发&#xff0c;安全稳定,系统支持代理、商户、码商等业务逻辑。 针对最近一些JD&#xff0c;TB等业务定制&#xff0c;子账号业务逻辑API 非常详细&#xff0c;方便内置…

Artec Leo 3D扫描仪 革新家具行业的数字化展示【沪敖3D】

随着科技的飞速进步&#xff0c;三维扫描技术已被广泛应用于包括家居行业在内的多个行业。面对现代消费者对家居产品日益增长的个性化和多样化需求&#xff0c;传统的家居设计和展示方法已难以满足市场需求。三维扫描技术的出现&#xff0c;为家居行业带来了新的发展机遇&#…

解决el-select数据量过大的3种方法

在准备上线的后台管理系统中&#xff0c;我们发现有两个下拉框&#xff08;select&#xff09;&#xff0c;其选项数据量超过 1 万条&#xff0c;而在测试环境中这些数据量只有几百条。这导致在页面加载时&#xff0c;浏览器性能出现瓶颈&#xff0c;页面卡顿甚至崩溃。 想了一…