二十三种设计模式全面解析-深入探究备忘录模式:保留过去,预见未来


在软件开发中,我们经常需要处理对象状态的保存和恢复问题。备忘录模式(Memento Pattern)提供了一种优雅的解决方案,能够在不破坏封装性的情况下,捕获和恢复对象的内部状态。本文将深入探讨备忘录模式的技术细节,包括适用场景、核心概念以及详细的实例代码,让您对备忘录模式有一个全面的了解。


1. 背景与引入

在软件开发中,我们经常遇到需要记录对象状态并能够在需要时恢复的情况。例如,一个文本编辑器可能需要支持撤销(Undo)和重做(Redo)操作,一个游戏可能需要保存游戏进度,以便在下次启动时恢复到之前的状态。此时,备忘录模式就能派上用场。


备忘录模式是一种行为型设计模式,它允许我们在不暴露对象内部细节的情况下,捕获和保存对象的状态,并在需要时将对象恢复到之前的状态。备忘录模式通过将状态保存在一个独立的备忘录对象中,实现了状态的封装和隔离,从而使得对象本身不需要关心状态的保存和恢复过程。


2. 核心概念

在备忘录模式中,通常涉及以下几个核心角色:

  • Originator(原发器):负责创建备忘录对象,并在需要时从备忘录对象中恢复自身状态。

  • Memento(备忘录):用于存储原发器对象的内部状态。备忘录可以有多个备份版本,每个版本都包含了原发器对象在某个时间点的状态快照。

  • Caretaker(管理者):负责保存和恢复备忘录对象。管理者可以保存多个备忘录对象,并在需要时选择特定的备忘录进行恢复。


备忘录模式的核心思想是通过将状态保存在备忘录对象中,让原发器对象与状态解耦。原发器对象只需要关注自身的业务逻辑,而不需要处理状态的保存和恢复。这种解耦使得系统更加灵活和可扩展。


3. 适用场景

备忘录模式在以下情况下特别有用:

  • 需要保存和恢复对象的内部状态,但又不希望将状态的实现细节暴露给其他对象。
  • 需要对对象进行撤销和重做操作,即能够在不破坏对象封装性的前提下,恢复到之前的状态。
  • 需要对对象进行快照和历史记录,以便进行版本管理或跟踪对象状态的变化。

备忘录模式能够有效地解决这些问题,并提供了一种灵活和可扩展的状态管理机制。


4. 案例代码实现

为了更好地理解备忘录模式,我们以一个文本编辑器为例,实现一个支持撤销和重做操作的编辑器。

首先,我们定义原发器类 Editor,它表示文本编辑器:


// 原发器类
class Editor {private String content;public Editor() {this.content = "";}public void type(String words) {this.content += words;}public String getContent() {return content;}public EditorMemento save() {return new EditorMemento(content);}public void restore(EditorMemento memento) {this.content = memento.getContent();}
}

然后,我们定义备忘录类 `EditorMemento`,用于保存编辑器的状态:
// 备忘录类
class EditorMemento {private final String content;public EditorMemento(String content) {this.content = content;}public String getContent() {return content;}
}

最后,我们定义管理者类 History,用于保存和管理备忘录对象:

// 管理者类
class History {private List<EditorMemento> mementos;public History() {this.mementos = new ArrayList<>();}public void push(EditorMemento memento) {mementos.add(memento);}public EditorMemento pop() {int lastIndex = mementos.size() - 1;EditorMemento lastMemento = mementos.get(lastIndex);mementos.remove(lastIndex);return lastMemento;}
}

现在,我们可以使用备忘录模式来实现撤销和重做操作:

public class Main {public static void main(String[] args) {Editor editor = new Editor();History history = new History();editor.type("Hello"); // 输入文本history.push(editor.save()); // 保存状态editor.type(" World!"); // 输入文本System.out.println(editor.getContent()); // 输出:Hello World!editor.restore(history.pop()); // 恢复状态System.out.println(editor.getContent()); // 输出:Hello}
}

在上面的例子中,我们使用 Editor 类表示文本编辑器,EditorMemento 类表示编辑器的状态快照,History 类用于管理备忘录对象。我们可以通过调用 save() 方法保存编辑器的状态,并通过调用 restore() 方法恢复到之前的状态。


备忘录模式为我们提供了一种灵活而强大的状态管理机制,使得对象的状态保存和恢复变得简单而优雅。它可以应用于各种场景,如撤销/重做操作、版本管理、游戏进度保存等。


然而,备忘录模式并不是万能的,它也有一些限制和注意事项。在实际使用中,我们需要权衡设计的复杂性和灵活性,选择适合的模式。


希望本文能够帮助您更好地理解备忘录模式,并激发您对于设计模式的探索和应用。

好了,今天的分享到此结束。如果觉得我的博文帮到了您,您的点赞和关注是对我最大的支持。如遇到什么问题,可评论区留言。


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

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

相关文章

【git error|SourceTree】error: bad signature 0x00000000 fatal: index file corrupt

报错 error: bad signature 0x00000000 fatal: index file corrupt 场景 在使用git add . 提交代码到缓冲区时或使用SourceTree时电脑宕机&#xff0c;重启后再次提交代码会出现该提示 原因分析 .git目录下的index文件损坏 解决方式 //删除索引文件 rm -f .git/index //回…

TCP/IP协议、三次握手、四次挥手

TCP/IP TCP/IP协议分层TCP头部三次握手TCP四次挥手常见问题1、什么是TCP网络分层2、TCP为什么是三次握手&#xff0c;不是两次或者四次&#xff1f;3、TCP为什么是四次挥手&#xff0c;为什么不能是三次挥手将第二次挥手和第三次挥手合并&#xff1f;4、四次挥手时为什么TIME_W…

ZKP11.4 Use CI to instantiate Fiat-Shamir

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.4 Use CI to instantiate Fiat-Shamir Avoid Bad Challenges Def: Given false claim x x x and a first message α \alpha α, a challenge β \beta …

再见 Pandas,再见算法

大家好,《再见pandas》 系列已有200多位朋友加入学习了,这段时间亲眼见证了很多朋友的飞跃进步,从无到有,从一个问问题的小白到开始慢慢回答别人的问题,在讨论和练习中不断成长。虽说pandas已经很普及了,但普及内容的深度却远远不够。 下面这套原创图文是我和几位小伙伴…

常用的git命令完整详细109条

Git是一个很强大的分布式版本控制系统&#xff0c;以下是一些常用的git命令&#xff1a; git init&#xff1a;在当前目录下创建一个新的Git仓库。git add 文件名&#xff1a;将指定的文件添加到暂存区&#xff0c;准备提交。git commit -m “备注”&#xff1a;提交暂存区的文…

C++ 数据结构之-最小栈(MinStack)

最小栈 最小栈&#xff08;Min Stack&#xff09;是一个支持常数时间复杂度获取栈中最小元素的特殊栈数据结构。通常&#xff0c;标准的栈数据结构只支持在常数时间内执行入栈&#xff08;push&#xff09;和出栈&#xff08;pop&#xff09;操作&#xff0c;但无法在常数时间内…

听说还有人不知道如何实现水平垂直居中?

HTML 代码部分 块级元素 <div class"parent"><div class"child">child</div> </div>行内元素 <div class"parent"><span class"child">child</span> </div>水平垂直居中 1、行内…

C++ STL map迭代器失效问题

最近在开发过程中&#xff0c;定位一个问题的时候&#xff0c;发现多线程场景下大量创建和销毁某个C:\Windows\System32\reg.exe时出现了383个进程创建消息处理的接口&#xff0c;和384个进程销毁处理消息的接口都在等待锁&#xff0c;另外一个线程也在等锁&#xff0c;后面看了…

mysql8下载与安装教程

文章目录 1. MySQL下载2. 方式一&#xff1a;msi文件安装2.1 安装2.2 添加环境变量2.3 登录mysql 3. 方式二&#xff1a;zip文件安装3.1 安装3.2 配置文件3.3 加入环境变量3.4 初始化mysql3.5 登录mysql 1. MySQL下载 以下两个网址二选一 官网&#xff1a;https://downloads.…

CPU、GPU、TPU内存子系统架构

文章目录 CPU、GPU、TPU内存子系统架构概要CPUGPUTPU共同点和差异&#xff1a; CPU、GPU、TPU内存子系统架构 概要 Memory Subsystem Architecture&#xff0c;图源自TVM CPU CPU&#xff08;中央处理器&#xff09;的内存子系统&#xff1a;隐式管理 主内存&#xff08;…

lv11 嵌入式开发 C工程与寄存器封装 10

目录 1 C语言工程介绍 1.1 工程模板介绍 1.2 启动代码分析 2 C语言实现LED实验 2.1 C语言如何实现寄存器读写 2.2 实现LED实验 2.3 练习 1 C语言工程介绍 1.1 工程模板介绍 工程目录&#xff0c;后续代码都会利用到这个目录 interface.c 写了一个main函数的框架 int …

BERT-pytorch源码实现,解决内存溢出问题

BERT-pytorch源码实现&#xff0c;解决内存溢出问题 相信大家很多人都在做BERT这个模型&#xff0c;但是&#xff0c;有些人可能就是直接从transfermer这个模型里直接导入数据&#xff0c;但是这种方法不方便我们修改模型&#xff0c;于是有些人就通过pytorch详细实现了BERT,但…

浏览器v8垃圾回收机制和内存泄漏分析-初级

借鉴&#xff1a;一文搞懂V8引擎的垃圾回收 - 掘金 (juejin.cn) 聊聊V8引擎的垃圾回收 - 掘金 (juejin.cn) 内存泄漏方向&#xff1a; 1、全局变量 未手动清除 2、定时器 未手动清除 3、闭包中使用了匿名函数 未手动清除 4、dom被赋值使用后 未手动清除 其他解决方式 1、…

均匀球形分布的随机三维单位向量

生成具有均匀球形分布的随机三维单位向量[参考] import numpy as np import matplotlib.pyplot as plt def random_three_vector():"""Generates a random 3D unit vector (direction) with a uniform spherical distributionAlgo from http://stackoverflow.c…

使用sizeof计算普通变量所占空间大小

// 32位WinNT操作系统环境下 char str[] "hello"; char *p str; int n 10;sizeof(str) sizeof(p) sizeof(n) void Func(char str[100]) {sizeof(str) }void *p malloc(100); sizeof(p) 解析&#xff1a; str变量表示数组&#xff0c;对数组变量做size…

区间预测 | Matlab实现BP-KDE的BP神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现BP-KDE的BP神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现BP-KDE的BP神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.BP-KDE多变量时间序列区间预测&#xff0c;基于BP神经网络多…

MFC 绘制单一颜色三角形、渐变颜色边框三角形、渐变填充三角形、正弦函数曲线实例

MFC 绘制三种不同圆形以及绘制正弦函数曲线 本文使用visual Studio MFC 平台实现绘制单一颜色圆形、渐变颜色边框圆形、渐变填充圆形以及绘制三角函数正弦函数曲线. 关于基础工程的创建请参考 01-Visual Studio 使用MFC 单文档工程绘制单一颜色直线和绘制渐变颜色的直线 02-vis…

Jenkins CI/CD

1、 Jenkins CI/CD 流程图 说明&#xff1a;这张图稍微更形象一点&#xff0c;上线之前先把代码git到版本仓库&#xff0c;然后通过Jenkins 如Java项目通过maven去构建&#xff0c;这是在非容器之前&#xff0c;典型的自动化的一个版本上线流程。那它有哪些问题呢&#xff1f; …

ASN.1 编码规则概述(一)

文章目录 一、ASN.1二、 ASN.1的标准编码规则分类三、描述ASN.1记法的标准四、描述ASN.1编码规则的标准 一、ASN.1 ASN.1&#xff08;Abstract Syntax Notation One) 是一套标准&#xff0c;是描述数据的表示、编码、传输、解码的灵活的记法&#xff0c;它提供了一套正式、 无…

C# 关于异常处理 try-catch语句的使用

在实际应用中&#xff0c;比如涉及文件读写、网络通信时&#xff0c;会因为文件不存在、权限不够、网络异常等原因引发异常&#xff0c;或者对数据库连接、查询、更新等操作&#xff0c;会因为连接超时、语法错误、唯一约束冲突等引发异常。 看过去的代码&#xff0c;当进行上…