设计模式——备忘录模式(Memento)

备忘录模式(Memento Pattern),也称为快照模式或Token模式,是GoF(Gang of Four,四位设计模式专家)提出的23种设计模式之一,属于行为模式。该模式的主要目的是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在适当的时候能够恢复到原先的状态。

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

  1. Originator(发起人):负责创建一个备忘录(Memento),用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
  2. Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象;而Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
  3. Caretaker(管理者):负责保存备忘录Memento,但不能对Memento的内容进行访问或者操作。

备忘录模式的优点包括:

  • 封装性:备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
  • 简化发起人:发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
  • 恢复机制:提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

然而,备忘录模式也有其缺点:

  • 资源消耗:如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
  • 存储空间未知:当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

以下是一个简单的备忘录模式(Memento Pattern)的Java代码示例。在这个示例中,我们有一个Originator类,它有一个内部状态,并可以创建和恢复其状态的备忘录。Memento类用于存储Originator的状态,而Caretaker类则负责保存和管理这些备忘录。

// 备忘录接口
interface Memento {// 这里可以定义一些方法来获取备忘录的状态
}// 具体的备忘录类
class OriginatorMemento implements Memento {private String state;public OriginatorMemento(String state) {this.state = state;}// 获取备忘录的状态(这里只是一个简单的getter方法)public String getState() {return state;}// 可能还有其他方法来设置状态,但在这个简单的例子中我们不需要
}// 发起人类
class Originator {private String state;// 创建一个备忘录并返回public Memento createMemento() {return new OriginatorMemento(this.state);}// 恢复备忘录中的状态public void restoreMemento(Memento memento) {this.state = ((OriginatorMemento) memento).getState();}// 设置发起人状态public void setState(String state) {this.state = state;}// 获取发起人状态public String getState() {return state;}
}// 管理者类
class Caretaker {private Memento memento;// 保存备忘录public void setMemento(Memento memento) {this.memento = memento;}// 获取备忘录public Memento getMemento() {return memento;}
}// 客户端代码
public class Client {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();// 设置发起人状态originator.setState("State 1");System.out.println("Current state: " + originator.getState());// 保存当前状态到备忘录caretaker.setMemento(originator.createMemento());// 修改发起人状态originator.setState("State 2");System.out.println("Current state: " + originator.getState());// 恢复之前保存的备忘录中的状态originator.restoreMemento(caretaker.getMemento());System.out.println("Restored state: " + originator.getState());}
}

在这个例子中,Originator类有一个state字段,它可以通过setState方法设置,并通过getState方法获取。createMemento方法创建一个OriginatorMemento对象,其中包含当前的staterestoreMemento方法接受一个Memento对象,并将其中的状态设置回Originatorstate字段。

Caretaker类用于保存Memento对象,并在需要时提供访问。

Client类中,我们创建了一个Originator和一个Caretaker对象,并演示了如何设置、保存和恢复Originator的状态。

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

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

相关文章

springboot中mybatisplus注意事项

使用代码生成工具CodeGenerator 需要修改的内容 dsc.setUsername(“root”); mysql账号dsc.setPassword(“root”); mysql密码strategy.setInclude(“crm_edu”); 表名pc.setModuleName(“eduservice”); //模块名 package com.test.demo;import com.baomidou.mybatisplus.a…

【超详细】跑通YOLOv8之深度学习环境配置2

环境配置2下载安装内容如下: CUDA:https://developer.nvidia.com/cuda-toolkit-archive cudnn:https://developer.nvidia.com/rdp/cudnn-archive 版本:CUDA11.3 cudnn8.9.7 CUDA安装 简介 CUDA(Compute Unified De…

vue如何进行webpack的配置

Vue.js 项目通常使用 Vue CLI 来创建和管理,它内置了 Webpack 作为构建工具。然而,如果你想要手动配置 Webpack 或者有特定的需求,你也可以在 Vue 项目中直接进行 Webpack 的配置。 下面是一个简单的步骤,介绍如何在 Vue 项目中手…

使用Python创建一个简单的任务管理器应用程序

在这篇文章中,我们将探讨如何使用Python和Tkinter库来创建一个简单但功能强大的任务管理器应用程序。这个应用程序将允许用户添加、编辑、删除和完成任务,并提供一个直观的用户界面。 1. 设计用户界面 我们首先设计用户界面。我们将使用Tkinter库来创建…

SEO之为什么研究关键词(一)

初创企业需要建站的朋友看这篇文章,谢谢支持: 我给不会敲代码又想搭建网站的人建议 新手上云 初做网站的人很容易犯的最大错误之一是,脑袋一拍就贸然进入某个领域,跳过竞争研究,没规划好目标关键词就开始做网站。这样做…

一个递推通项公式研究

递推关系为a(n) ​pa(n−1) ​ qa(n−2) ​,本项前一项*2前前项,具体如 1,1,3,7,17,41,99,239,…… 一般的递推关系可以用以下方法 得两个解: …

python算法demo0512

最长回文数 代码 class Solution:def longestPalindrome(self, s: str) -> str:n len(s)if n < 2:return smax_len 1begin 0# dp[i][j] 表示 s[i..j] 是否是回文串dp [[False] * n for _ in range(n)]for i in range(n):dp[i][i] True# 递推开始# 先枚举子串长度fo…

windows窗口消息队列与消息过程处理函数

在Windows窗口应用程序中&#xff0c;消息队列和窗口过程函数是实现消息驱动机制的核心组件。 消息队列&#xff08;Message Queue&#xff09;&#xff1a; 消息队列是用于存储窗口消息的缓冲区。当用户与应用程序交互时&#xff0c;系统会将生成的消息插入到消息队列中&…

cae仿真软件是啥

CAE&#xff08;Computer Aided Engineering&#xff09;仿真软件是一种专门用于工程设计和分析的软件&#xff0c;它集成了计算机科学、物理学、数学等多个领域的知识&#xff0c;能够对复杂的工程系统进行建模、仿真和分析。CAE软件通过数值计算和模拟技术&#xff0c;可以模…

十三、Redis哨兵模式--Sentinel

上一篇介绍了Redis中的主从复制。我们知道Redis主从中一般只有主节点对外提供写操作&#xff0c;如果主节点发生故障&#xff0c;为了保证Redis的可用性&#xff0c;这时就要在可用的slave节点中&#xff0c;挑选一个作为主节点。这种切换操作如果是人为的操作&#xff0c;那么…

支持播放h265的插件

插件源码地址&#xff1a;GitCode - 开发者的代码家园https://gitcode.com/mirrors/nanguantong/flv-h265.js/overview 1. 下载代码 运行以下命令 npm i npm run build npm run build 后生成 flv.min.js 文件&#xff0c;引入使用 2. 调用 js 文件&#xff1a; let flvj…

关于-RTSP推流方案, ffmpeg 视频转 m3u8

参考文章 https://zhuanlan.zhihu.com/p/668110375 增加fmpeg 执行单个视频推流 ffmpeg -re -stream_loop -1 -i 你视频的文件名 -c copy -f rtsp rtsp://127.0.0.1:8554/videohttps://blog.csdn.net/EthanCo/article/details/125321957 Windows下安装使用ffmpeg https://z…

uniapp开发小程序使用vue的v-html解析富文本图片过大过宽显示超过屏幕解决办法

如果没有设置的话&#xff0c;就会导致图片溢出&#xff0c;过宽显示或者错位显示&#xff0c;显示效果非常的丑陋&#xff1a; 修改后显示的效果&#xff1a; 网上比较low的解决办法&#xff1a;网上各种解决方法核心思想就是在数据层把数据模板上的img数据加上style样式&…

简要介绍三大脚本语言 Shell、Python 和 Lua

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 脚本语言是一种用于自动化操作系统任务和应用程序功能的编程语言。它们通常用于编写小到中等规模的程序&#xff0c;以提高任务执行的速度和效率。在众多脚本语言中&#xff0c;Shell、Python 和 Lua 是…

详解AI算法作画原理

AI作画算法的原理主要基于深度学习和计算机视觉技术&#xff0c;特别是生成对抗网络&#xff08;GANs&#xff09;和卷积神经网络&#xff08;CNNs&#xff09;等模型。以下是AI作画算法原理的详细解释&#xff1a; 数据收集与处理&#xff1a; AI作画的第一步是收集大量的艺术…

多线程之交替输出abc

1、wait notify 版 public class SyncWaitNotify {//打印标识&#xff1a;1打印a&#xff0c;2打印b&#xff0c;3打印cprivate int flag;//每个字母的打印次数private int loopNumber;//构造方法public SyncWaitNotify(int flag, int loopNumber) {this.flag flag;this.loop…

无人机姿态模式(Attitude Mode)和导航模式(Navigation Mode)以及自动模式的区别

姿态模式&#xff08;Attitude Mode&#xff09;和导航模式&#xff08;Navigation Mode&#xff09;是无人机飞行控制系统中两种基本的飞行模式&#xff0c;它们在飞行控制和操作上有着显著的区别&#xff1a; 姿态模式&#xff1a; 在姿态模式下&#xff0c;飞控主要关注维…

重发布和路由策略实验(课堂练习)

需求&#xff1a; 将1.1.1.0/24网段&#xff08;不在OSPF中&#xff09;重发布到网络中&#xff0c;不允许出现次优路径&#xff0c;实现全网可达。 需求分析&#xff1a; 1、在R1上重发布1.1.1.0/24网段&#xff0c;但是需要过滤192.168.12.0/24和192.168.13.0/24 2、在R2和R3…

网络编程学习笔记1

文章目录 一、socket1、创建socket2、网络通信流程3、accept()函数4、signal()函数5、recv()函数6、connect()函数 二、I/O多路复用1.select模型2.poll模型3.epoll模型 注 一、socket 1、创建socket int socket(int domain,int type,int protocol); //返回值&#xff1a;一个…

linq常用方法

1.Where - 用于筛选满足特定条件的元素。 var query list.Where(x > x > 10); 2.Select - 用于投影每个元素到一个新的形式。这通常用于转换数据的形状。 var query list.Select(x > x * x); 3.OrderBy / OrderByDescending - 用于对元素进行升序或降序排序。 var…