备忘录模式的理解和实践

引言

        在软件开发中,我们经常会遇到需要保存对象状态并在某个时间点恢复到该状态的需求。这种需求类似于我们平时说的“后悔药”,即允许用户撤销之前的操作,恢复到某个之前的状态。备忘录模式(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,一经查实,立即删除!

相关文章

day35—蓝桥杯2024年第16届校赛模拟第二期-T4(最小花费)

【问题描述】 小蓝有一个整数&#xff0c;初始值为 1 &#xff0c;他可以花费一些代价对这个整数进行变换。 小蓝可以花费 1 的代价将整数增加 1 。 小蓝可以花费 3 的代价将整数增加一个值&#xff0c;这个值是整数的数位中最大的那个&#xff08;1 到 9&#xff09;。 小蓝可…

Vue.js面试题

0. Vue.js 做了些什么&#xff1f; Vue.js 作为现代前端框架&#xff0c;提供了一系列功能和工具&#xff0c;帮助开发者更高效地开发 Web 应用。它不仅是一个简单的 UI 渲染库&#xff0c;还涵盖了很多与开发效率、应用结构、性能优化相关的内容。Vue 的核心特性包括&#xf…

LVGL9 标尺控件 (lv_scale) 使用指南

文章目录 前言主体1. **控件概述**2. **控件的样式和组成部分**3. **使用场景**4. **控件的基本使用**设置范围配置刻度设置刻度长度添加分段 5. **键盘和事件支持**键盘支持事件支持 6. **示例代码** 总结 前言 标尺控件&#xff08;lv_scale&#xff09;是 LittlevGL 提供的…

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

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

30天学会Go--第7天 GO语言 Redis 学习与实践(改)

30天学会Go–第7天 GO语言 Redis 学习与实践&#xff08;改&#xff09; 文章目录 30天学会Go--第7天 GO语言 Redis 学习与实践&#xff08;改&#xff09;前言一、Redis 基础知识1.1 Redis 的核心特性1.2 Redis 常见使用场景 二、安装 Redis2.1 在 Linux 上安装2.2 在 Windows…

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;便能轻松找到需要的物品。这个小…

OpenStack介绍

OpenStack概述 OpenStack是一个开源的云计算管理平台软件,主要用于构建和管理云计算环境。它允许企业或组织通过数据中心的物理服务器创建和管理虚拟机、存储资源和网络等云计算服务。其核心组件包括计算(Nova)、网络(Neutron)、存储(Cinder、Swift)等。这些组件相互协作…

ftp服务器搭建-安装、配置及验证

ftp服务器搭建-安装、配置及验证 #安装 sudo apt-get install vsftpd #配置文件 cat > /etc/vsftpd.conf << "EOF" listenNO listen_ipv6YES anonymous_enableNO local_enableYES write_enableYES dirmessage_enableYES use_localtimeYES xferlog_enable…

搭建高可用负载均衡系统: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;跳转页面的时…