【重温设计模式】备忘录模式及其Java示例

news2024/11/15 21:49:03

备忘录模式的概述

在软件设计的世界中,备忘录模式是一种行为设计模式,它的主要作用是保存对象的当前状态,以便在将来的某个时间点,可以将对象恢复到这个保存的状态。这种模式的命名源于生活中的备忘录,我们常常用它来记录一些重要的信息,以防忘记。

在编程中,备忘录模式的重要性不言而喻。想象一下,你正在编写一个复杂的程序,用户可能会进行一系列的操作,然后突然想要撤销某个操作。如果没有备忘录模式,你可能需要手动跟踪用户的每一个操作,然后编写复杂的代码来撤销这些操作。但是,有了备忘录模式,你只需要在每次操作前保存一下当前的状态,然后在需要撤销操作时,直接恢复到之前保存的状态即可。

接下来,我们将详细解释备忘录模式的三个主要组成部分:发起人、备忘录和管理者,以及他们各自的职责和角色。

备忘录模式的组成部分

在我们深入探讨备忘录模式的内部机制之前,我们需要了解其三个主要的组成部分:发起人、备忘录和管理者。每个部分都有其特定的职责和角色,他们的协同工作使得备忘录模式能够正常运作。

首先,发起人是我们想要保存状态的对象。它可以创建一个包含其当前内部状态的备忘录,并在需要时使用备忘录恢复其内部状态。在Java中,我们可以通过定义一个发起人类来实现这一角色。例如,我们可以创建一个名为OneMore的类,该类有一个state字段用于保存其状态,以及createMemento()restoreMemento()方法用于创建备忘录和恢复状态。

public class OneMore {
    private String state;

    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }
}

其次,备忘录是一个用于保存发起人对象状态的对象。它只能被发起人访问,但不能被其他对象访问。在Java中,我们可以通过定义一个备忘录类来实现这一角色。例如,我们可以创建一个名为Memento的类,该类有一个state字段用于保存发起人的状态。

最后,管理者负责保存备忘录,但不能对备忘录的内容进行操作或检查。在Java中,我们可以通过定义一个管理者类来实现这一角色。例如,我们可以创建一个名为Caretaker的类,该类有一个memento字段用于保存备忘录。

通过这三个角色的互动,我们可以在任何时候保存对象的状态,并在需要时恢复到之前的状态。接下来,我们将通过一个具体的例子来看看如何在Java中实现备忘录模式。

Java中的备忘录模式实例

在Java中,我们可以通过具体的代码来实现备忘录模式。以文本编辑器为例,用户可能会对一段文字进行很多次修改。在这种情况下,我们可以使用备忘录模式来保存当前文本的状态。

首先,我们需要创建一个名为OneMoreEditor的“发起人”类,这是我们想要保存状态的对象。这个类中,我们需要有一个content字段来保存当前的文本状态,以及一个createMemento()方法来创建备忘录,一个restore(Memento memento)方法来恢复状态。

public class OneMoreEditor {
    private String content;

    public Memento createMemento() {
        return new Memento(content);
    }

    public void restore(Memento memento) {
        this.content = memento.getContent();
    }

    // other methods...
}

接着,我们需要一个名为Memento的“备忘录”类,它可以保存“发起人”的状态。这个类中,我们需要有一个content字段来保存状态,以及一个getContent()方法来获取状态。

public class Memento {
    private String content;

    public Memento(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}

最后,我们需要一个名为Caretaker的“看护人”类,它可以保存备忘录,并在需要时将“发起人”的状态恢复到备忘录中的状态。这个类中,我们需要有一个memento字段来保存备忘录,以及一个saveMemento(Memento memento)方法来保存备忘录,一个getMemento()方法来获取备忘录。

public class Caretaker {
    private Memento memento;

    public void saveMemento(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

这样,我们就实现了一个简单的备忘录模式。

create
use
use
OneMoreEditor
-String content
+createMemento()
+restore(Memento memento)
Memento
-String content
+Memento(String content)
+getContent()
Caretaker
-Memento memento
+saveMemento(Memento memento)
+getMemento()

用户可以通过OneMoreEditor进行文本编辑,通过Caretaker保存和恢复状态。但是,备忘录模式并非完全无懈可击,它同样有其优点和缺点,这需要我们在实际开发中根据实际需求进行选择。

备忘录模式的优缺点

备忘录模式,如同一位细心的记事人,为我们的软件设计提供了一种保存和恢复对象状态的机制。如同世间万物,它也有其优点和缺点,理解这些,可以帮助我们在实际开发中更好的选择和使用。

首先,让我们来看看备忘录模式的优点。备忘录模式的最大优点就是它可以保持封装的完整性。备忘录有两个接口,一个是宽接口,对发起人开放,允许其访问所有信息;另一个是窄接口,对其他对象开放,只允许其看到备忘录的保留接口。这样,除了发起人,其他对象无法访问备忘录的内部信息,从而保证了封装的完整性。

然后,我们来看看备忘录模式的缺点。备忘录模式的主要缺点在于资源消耗。因为每次保存状态都需要创建一个备忘录对象,如果我们需要保存大量的状态信息,或者需要频繁地保存状态,那么这将消耗大量的内存资源。

在实际开发中,我们是否选择使用备忘录模式,需要根据实际需求来决定。如果我们的系统需要提供撤销操作,或者需要保存对象的某个历史状态,备忘录模式是一个很好的选择。但是,如果系统资源紧张,或者不需要保存状态,我们就应该避免使用备忘录模式。

总结

备忘录模式,就像一个时间机器,让我们可以自由地穿梭在时间的长河中。但是,每一次的穿梭,都会消耗一部分的资源。因此,我们需要明智地使用这个模式,根据实际的需求来决定是否需要保存状态,以及何时保存状态。如果我们过于频繁地保存状态,可能会消耗大量的资源,导致系统的性能下降。但是,如果我们能够合理地使用这个模式,它将会是我们的强大工具。

没有完全正确或者完全错误的设计模式,只有适合或者不适合的使用场景。备忘录模式,就是这样一个有优点也有缺点的设计模式。它能够帮助我们保存和恢复对象的状态,但同时也需要消耗一定的资源。因此,我们在使用这个模式时,需要根据实际的需求和资源情况来做出决定。

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

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

相关文章

图机器学习(4)-面向连接层面的人工特征工程

0 问题定义 通过已经连接去猜未知连接: 有两个思路: (1)直接提取link的特征,把link变成D维向量; (2)把link两端节点的D维向量拼在一起,缺点:丢失了link本身…

JavaScript极速入门-综合案例(3)

综合案例 猜数字 预期效果 代码实现 <button type"button" id"reset">重新开始一局游戏</button><br>请输入要猜的数字:<input type"text" id"number"><button type"button" id"button&q…

php使用ElasticSearch

ElasticSearch简介 Elasticsearch 是一个分布式的、开源的搜索分析引擎&#xff0c;支持各种数据类型&#xff0c;包括文本、数字、地理、结构化、非结构化。 Lucene与ElasticSearch Apache Lucene是一款高性能的、可扩展的信息检索&#xff08;IR&#xff09;工具库&#xf…

算法学习06:数组模拟:单/双链表,栈和队列,单调栈/队列

算法学习06&#xff1a;数组模拟&#xff1a;单/双链表&#xff0c;栈和队列&#xff0c;单调栈/队列 文章目录 算法学习06&#xff1a;数组模拟&#xff1a;单/双链表&#xff0c;栈和队列&#xff0c;单调栈/队列前言一、链表1.单链表2.双链表 二、栈和队列1.普通栈、队列2.单…

[LeetCode][102]二叉树的层序遍历——遍历结果中每一层明显区分

题目 102. 二叉树的层序遍历 给定二叉树的根节点 root&#xff0c;返回节点值的层序遍历结果。即逐层地&#xff0c;从左到右访问所有节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]] 示例 2&#xff1a; 输入…

【计算机网络】TCP 的三次握手与四次挥手

通常我们进行 HTTP 连接网络的时候会进行 TCP 的三次握手&#xff0c;然后传输数据&#xff0c;之后再释放连接。 TCP 传输如图1所示&#xff1a; 图1 TCP 传输 TCP三次握手的过程如下&#xff1a; 第一次握手&#xff1a;建立连接。客户端发送连接请求报文段&#xff0c;将 …

深度学习模型部署(四)常用模型及推理平台评估指标

判断选择什么模型&#xff0c;什么量化方案&#xff0c;什么推理框架&#xff0c;最基础的知识就是如何评估自己的模型以及推理平台。 模型衡量标准 衡量一个模型的最直接标准就是运算速度&#xff0c;但是运算速度是无法计算的&#xff0c;所以定义了一些间接标准来推测模型的…

探索数据可视化:Matplotlib 基础指南

图形绘制 import numpy as np import pandas as pd import matplotlib.pyplot as pltx np.linspace(0,2 * np.pi,100)# 说明&#xff1a;正弦波。x&#xff1a;NumPy数组 # 所有的数据&#xff0c;进行正弦计算 y np.sin(x)plt.plot(x,y)# 指定x轴范围 plt.xlim(-1,10) # 指…

99%的商业模式都是可借鉴,解读法国葡萄酒庄长盛不衰的经营模式?

99%的商业模式都是可借鉴&#xff0c;解读法国葡萄酒庄长盛不衰的经营模式&#xff1f; 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 引言&#xff1a;很多朋友说到葡萄酒&#xff0c;有的第一印象就是“法国葡萄酒”…

全面对比Amazon DocumentDB 与 MongoDB

在云中部署 MongoDB 似乎有多种选择。例如&#xff0c;Amazon DocumentDB自称是完全支持 MongoDB API 的 AWS 原生数据库。虽然它支持一些 MongoDB 功能&#xff0c;但需要注意的是 DocumentDB 并不完全兼容 MongoDB。要在 AWS 上访问功能齐全的“MongoDB 即服务”&#xff0c;…

CCProxy代理服务器地址的设置步骤

目录 前言 一、下载和安装CCProxy 二、启动CCProxy并设置代理服务器地址 三、验证代理服务器设置是否生效 四、使用CCProxy进行代理设置的代码示例 总结 前言 CCProxy是一款常用的代理服务器软件&#xff0c;可以帮助用户实现网络共享和上网代理。本文将详细介绍CCProxy…

用Python实现一个简单的——人脸相似度对比

近几年来&#xff0c;兴起了一股人工智能热潮&#xff0c;让人们见到了AI的能力和强大&#xff0c;比如图像识别&#xff0c;语音识别&#xff0c;机器翻译&#xff0c;无人驾驶等等。总体来说&#xff0c;AI的门槛还是比较高&#xff0c;不仅要学会使用框架实现&#xff0c;更…

Windows上websocket客户端连接定时存储消息到文件并加载文件定时发送服务端工具实现

场景 在业务开发中&#xff0c;需要对接三方websocket协议数据或者连接并存储线上websocket协议数据&#xff0c;需要使用websocket客户端 连接线上的websocket服务端获取并存储数据&#xff0c;然后将数据存储成文件格式可移植&#xff0c;并将数据复制 到本地&#xff0c;…

15. C++泛型与符号重载

【泛型编程】 若多组类型不同的数据需要使用相同的代码处理&#xff0c;在C语言中需要编写多组代码分别处理&#xff0c;这样做显然太过繁琐&#xff0c;C增加了虚拟类型&#xff0c;使用虚拟类型可以实现一组代码处理多种类型的数据。 虚拟类型是暂时不确定的数据类型&#…

免费的文案二次创作软件,打造高质量原创文案

在当今数字化时代&#xff0c;内容创作已经成为企业和个人推广自身品牌、产品和服务的重要手段。然而&#xff0c;对于许多人来说&#xff0c;撰写高质量的原创文案并非易事。幸运的是&#xff0c;随着技术的发展&#xff0c;出现了许多文案二次创作免费软件&#xff0c;为那些…

怎么做不限扫码次数的文件活码?文件可长期扫描展现下载

如何制作不限扫码次数的文件二维码呢&#xff1f;将文件转二维码后分享给其他人&#xff0c;是现在非常方便的一种文件传输方式。很多小伙伴在制作文件二维码的时候&#xff0c;比较担心的一个问题&#xff0c;就是二维码可以扫码的次数&#xff0c;担心达不到自己预期的效果&a…

保姆级讲解 Stable Diffusion

目录 本文讲解思路介绍 一、引入 二、Diffusion Model 三、原文的摘要和简介 四、Stable Diffusion 4.1、组成模块 4.2、感知压缩 4.3、条件控制 五、图解 Stable Diffusion 5.1、潜在空间的扩散 5.2、条件控制 5.3、采样 5.4、Diffusion Model 与 Stable Diffusion …

win11+wsl+ubuntu20.04+ros+x11+mobaxterm实现win11中ROS使用(含可视化)

前言 为实现在win11中使用ros… 一、win11中wsl(ubuntu20.04)安装 参考&#xff1a;Windows 11 安装 WSL2 主要步骤&#xff1a;开启虚拟化–>安装ubuntu20.04 安装后可能还是WSL1&#xff0c;可参考WSL1升级为WSL2进行升级。 二、使用鱼香ROS换源并更新 wget http://fishro…

【刷题记录】详谈设计循环队列

下题目为个人的刷题记录&#xff0c;在本节博客中我将详细谈论设计循环队列的思路&#xff0c;并给出代码&#xff0c;有需要借鉴即可。 题目&#xff1a;LINK 循环队列是线性表吗&#xff1f;或者说循环队列是线性结构吗&#xff1f; 对于这个问题&#xff0c;我们来看一下线…

Awesome-Backbones-main——alexnet模型分析

AlexNet作为骨干网络相对较老&#xff0c;可能在复杂数据集上的表现不如一些最新的深度网络结构&#xff0c;如ResNet、EfficientNet等&#xff0c;学习率调整策略中采用了阶梯式学习率更新器&#xff0c;可能并不总是适合所有数据集和模型&#xff0c;需要根据具体情况调整学习…