备忘录模式(行为型)

目录

一、前言

二、备忘录模式

三、总结


一、前言

        备忘录模式(Memento Pattern)是一种行为型设计模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在之后将该对象恢复到原来保存的状态。

        备忘录模式由以下几个角色组成:

Originator(发起人):

负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复状态。Originator可根据需求决定Memento存储Originator的哪些内部状态

Memento(备忘录):

负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。

Caretaker(管理者):

负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查

        整个备忘录模式的类图:

二、备忘录模式

        比如常见的游戏存档,大部分会在进行某项重要任务之前存档,任务要是失败,可以读档,避免损失,这种情况使用备忘录模式就能很好实现存档读档。

        根据备忘录模式,我们可以有以下代码:

        首先创建Originator类:

/*** @Author dengyifan* @create 2024/4/30 14:04* @description 发起人类*/
public class Originator {private String name;private String address;private Integer blood;private Integer vigor;public Originator(String name, String address, Integer blood, Integer vigor) {this.name = name;this.address = address;this.blood = blood;this.vigor = vigor;}public void recover(Memento memento){this.name = memento.getName();this.address = memento.getAddress();this.blood = memento.getBlood();this.vigor = memento.getVigor();}public Memento save(){return new Memento(name,address,blood,vigor);}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getBlood() {return blood;}public void setBlood(Integer blood) {this.blood = blood;}public Integer getVigor() {return vigor;}public void setVigor(Integer vigor) {this.vigor = vigor;}@Overridepublic String toString() {return "Originator{" +"name='" + name + '\'' +", address='" + address + '\'' +", blood=" + blood +", vigor=" + vigor +'}';}
}

        创建Memento类:

/*** @Author dengyifan* @create 2024/4/30 14:12* @description 备忘录类,实际参数等是发起人里面的参数*/
public class Memento {private String name;private String address;private Integer blood;private Integer vigor;public Memento(String name, String address, Integer blood, Integer vigor) {this.name = name;this.address = address;this.blood = blood;this.vigor = vigor;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getBlood() {return blood;}public void setBlood(Integer blood) {this.blood = blood;}public Integer getVigor() {return vigor;}public void setVigor(Integer vigor) {this.vigor = vigor;}}

        创建Caretaker类:

/*** @Author dengyifan* @create 2024/4/30 14:12* @description 管理类*/
public class Caretaker {private Memento memento;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}
}

        客户端调用测试:

/*** @Author dengyifan* @create 2024/4/30 14:12* @description*/
public class Client {public static void main(String[] args) {// 开始状态Originator originator = new Originator("林克","海拉鲁", 30, 15);System.out.println("初始状态:" + originator);// 存档Caretaker caretaker = new Caretaker();caretaker.setMemento(originator.save());// 消耗originator.setBlood(5);originator.setVigor(5);System.out.println("消耗后:" + originator);// 读档originator.recover(caretaker.getMemento());System.out.println("读取后:" + originator);}
}

        测试结果:

三、总结

        优点与缺点:

优点:

1、提供了一种状态恢复的实现机制:当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。这对于一些需要频繁撤销操作或恢复状态的应用场景非常有用。

2、实现了对信息的封装:备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。这有助于保持代码的封装性和可维护性。

3、简化了发起人类:发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。这有助于减少发起人类的复杂性和工作量。

4、有利于保护封装边界:使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界

缺点:

1、资源消耗较大:如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间。每保存一次对象的状态都需要消耗一定的系统资源。

2、负责人可能无法预知存储空间消耗:当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

        使用场景:

1、撤销操作:备忘录模式适用于保存/恢复数据的相关业务场景,如Word中编写文档时,如果想要撤销之前的输入/删除操作,可以使用Ctrl+Z执行“撤销”操作。

2、状态恢复:在需要“后悔”的时候,将对象恢复到之前的状态,如游戏中的存档使用。

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

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

相关文章

idea生成双击可执行jar包

我这里是一个生成xmind,解析sql的一个main方法,可以通过配置文件来修改有哪些类会执行 我们经常会写一个处理文件的main方法,使用时再去寻找,入入会比较麻烦,这里就可以把我们写过的main方法打成jar包,放到指定的目录来处理文件并生成想要的结果 1.写出我们自己的main方法,本地…

C语言.自定义类型:结构体

自定义类型:结构体 1.结构体类型的声明1.1结构体回顾1.1.1结构体的声明1.1.2结构体变量的创建和初始化 1.2结构体的特殊声明1.3结构体的自引用 2.结构体内存对齐2.1对齐规则2.2为什么存在内存对齐2.3修改默认对齐数 3.结构体传参4.结构体实现位段4.1什么是位段4.2位…

深入浅出DBus-C++:Linux下的高效IPC通信

目录标题 1. DBus简介2. DBus-C的优势3. 安装DBus-C4. 使用DBus-C初始化和连接到DBus定义接口和方法发送和接收信号 5. dbus-cpp 0.9.0 的安装6. 创建一个 DBus 服务7. 客户端的实现8. 编译和运行你的应用9. 瑞芯微(Rockchip)的 Linux 系统通常会自带 db…

OpenLayers入门①(引入的是一个高德地图)

OpenLayers入门&#xff08;一&#xff09; - 知乎 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&qu…

使用RTSP将笔记本摄像头的视频流推到开发板

一、在Windows端安装ffmpeg 1. 下载ffmpeg:下载ffmpeg 解压ffmpeg-master-latest-win64-gpl.zip bin 目录下是 dll 动态库 , 以及 可执行文件 ;将 3 33 个可执行文件拷贝到 " C:\Windows " 目录下 ,将所有的 " .dll " 动态库拷贝到 " C:\Windows\Sy…

期权交割对股市是好是坏?2024期权交割日一览表

期权交割是指期权买方在期权合约到期日或之前行使期权&#xff0c;卖方履行义务&#xff0c;按照约定的价格和数量与期权卖方进行标的物的买卖或现金结算的过程。 交割方式 期权交割可以分为实物交割和现金交割&#xff0c;具体取决于合约规定。 实物交割 实物交割是指期权买…

【深度学习基础(1)】什么是深度学习,深度学习与机器学习的区别、深度学习基本原理,深度学习的进展和未来

文章目录 一. 深度学习概念二. 深度学习与机器学习的区别三. 理解深度学习的工作原理1. 每层的转换进行权重参数化2. 怎么衡量神经网络的质量3. 怎么减小损失值 四. 深度学习已取得的进展五. 人工智能的未来 - 不要太过焦虑跟不上 一. 深度学习概念 先放一张图来理解下人工智能…

Vue阶段练习:初始化渲染、获取焦点

阶段练习主要承接Vue 生命周期-CSDN博客 &#xff0c;学习完该部分内容后&#xff0c;进行自我检测&#xff0c;每个练习主要分为效果显示、需求分析、静态代码、完整代码、总结 四个部分&#xff0c;效果显示和准备代码已给出&#xff0c;我们需要完成“完整代码”部分。 练习…

MySQL__三大日志

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a;Redis__三大日志 ⏱️ 创作时间&#xff1a;2024年04月30日 ———————————————— 对于MySQL来说, 有…

Gateway Predicate断言(谓词)

是什么 Spring Cloud Gateway匹配路由作为Spring WebFlux HandlerMapping基础设施的一部分。 Spring Cloud Gateway包含许多内置的路由谓词工厂。 所有这些谓词都匹配HTTP请求的不同属性。 您可以使用逻辑 and 语句来联合收割机组合多个路由谓词工厂。 Predicate就是为了实现一…

基于EBAZ4205矿板的图像处理:03使用VIO调试输出HDMI视频图像

基于EBAZ4205矿板的图像处理&#xff1a;03使用VIO调试输出HDMI视频图像 在zynq调试时VIO是真的方便&#xff0c;特此写一篇博客记录一下 先看效果 项目简介 下面是我的BD设计&#xff0c;vtc用于生成时序&#xff0c;注意&#xff0c;2021.2的vivado的vtcIP是v6.2版本&…

Stm32CubeMX 为 stm32mp135d 添加 adc

Stm32CubeMX 为 stm32mp135d 添加 adc 一、启用设备1. adc 设备添加2. adc 引脚配置2. adc 时钟配置 二、 生成代码1. optee 配置 adc 时钟和安全验证2. linux adc 设备 dts 配置 bringup 可参考&#xff1a; Stm32CubeMX 生成设备树 一、启用设备 1. adc 设备添加 启用adc设…

JAVA前端快速入门基础_javascript入门(03)

写在前面:本文用于快速学会简易的JS&#xff0c;仅做扫盲和参考作用 本章节主要介绍JS的事件监听 1.什么是事件监听 事件:是指发生在HTML端的事件&#xff0c;主要指以下几种。 1.按钮被点击 2.鼠标移动到元素上 3.按到了键盘 事件监听:当触发了事件时&#xff0c;JS会执行相…

vue3、element-plus递归实现动态菜单

vue3、element-plus递归实现动态菜单 使用场景&#xff1a;动态菜单为什么使用递归递归在动态菜单中的实现 使用场景&#xff1a;动态菜单 动态菜单是指菜单项的数量和层次结构可能是动态的&#xff0c;通常来自后端或用户输入。这些菜单的特征包括&#xff1a; 多层嵌套&…

【webrtc】MessageHandler 3: 基于线程的消息处理:以sctp测试为例

消息处理可以用于模拟发包处理G:\CDN\rtcCli\m98\src\net\dcsctp\socket\dcsctp_socket_network_test.cc 这个实现中,onMessage还是仅对了一种消息进行处理,就是接收则模式下,打印带宽。当然,可能程序有多个消息,分别在不同的onmessage中执行?SctpActor:以一个恒定的速率…

【大语言模型LLM】-基于ChatGPT搭建客服助手(1)

&#x1f525;博客主页&#xff1a;西瓜WiFi &#x1f3a5;系列专栏&#xff1a;《大语言模型》 很多非常有趣的模型&#xff0c;值得收藏&#xff0c;满足大家的收集癖&#xff01; 如果觉得有用&#xff0c;请三连&#x1f44d;⭐❤️&#xff0c;谢谢&#xff01; 长期不…

利用大型语言模型提升个性化推荐的异构知识融合方法

在推荐系统中&#xff0c;分析和挖掘用户行为是至关重要的&#xff0c;尤其是在美团外卖这样的平台上&#xff0c;用户行为表现出多样性&#xff0c;包括不同的行为主体&#xff08;如商家和产品&#xff09;、内容&#xff08;如曝光、点击和订单&#xff09;和场景&#xff0…

C++ 堆结构和堆排序(从顶到底/从底到顶的大顶堆)+ 优化

一、堆结构和堆排序 &#xff08;1&#xff09;heapInsert&#xff0c;向上调整大根堆 和 heapify&#xff0c;向下调整大根堆 // i位置的数&#xff0c;向上调整大根堆 // arr[i] x&#xff0c;x是新来的&#xff01;往上看&#xff0c;直到不比父亲大&#xff0c;或者来到0…

使用Gradio搭建聊天UI实现质谱AI智能问答

一、调用智谱 AI API 1、获取api_key 智谱AI开放平台网址&#xff1a; https://open.bigmodel.cn/overview 2、安装库pip install zhipuai 3、执行一下代码&#xff0c;调用质谱api进行问答 from zhipuai import ZhipuAIclient ZhipuAI(api_key"xxxxx") # 填写…

短视频交友系统搭建重点,会用到哪些三方服务?

在搭建短视频交友系统时&#xff0c;为了确保系统的稳定性、安全性和用户体验&#xff0c;通常需要用到多种第三方服务。以下是搭建短视频交友系统时可能用到的关键第三方服务&#xff1a; 云服务提供商&#xff1a;如阿里云、腾讯云等&#xff0c;提供稳定、可扩展的服务器资源…