当前位置: 首页 > news >正文

(二 十 二)趣学设计模式 之 备忘录模式!

在这里插入图片描述

目录

    • 一、 啥是备忘录模式?
    • 二、 为什么要用备忘录模式?
    • 三、 备忘录模式的实现方式
    • 四、 备忘录模式的优缺点
    • 五、 备忘录模式的应用场景
    • 六、 总结

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解访问者模式请看: (二 十 一)趣学设计模式 之 访问者模式!
✨更多请看个人主页: 码熔burning

这篇文章带你详细认识一下设计模式中的备忘录模式

一、 啥是备忘录模式?

想象一下,你在玩一个游戏 🎮,你打到了一个很高的分数,但是你怕后面会失误,导致分数降低 📉。 这时候,你可以保存一个游戏存档 💾,这样即使你后面失误了,也可以读档回到之前的状态 🕹️。

备忘录模式,就是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态! 简单来说,就是给对象做一个“快照”,方便以后恢复 📸。

简单来说,就是给对象创建一个“存档点”,以便在需要的时候可以“读档重来”! 💾+🕹️

  • 你需要保存一个对象的内部状态,以便以后可以恢复: 就像你需要保存游戏存档,以便在失误后可以读档 🎮!
  • 你不想破坏对象的封装性: 就像你不想直接访问游戏内部的数据,而是通过存档来保存状态 💾!
  • 你需要支持撤销操作: 就像你需要支持游戏中的“悔棋”功能 🔙!

二、 为什么要用备忘录模式?

用备忘录模式,好处多多 👍:

  • 保存状态: 可以保存对象的内部状态,方便以后恢复 💾!
  • 保护封装性: 不破坏对象的封装性 🔒!
  • 支持撤销: 可以支持撤销操作 🔙!
  • 简化对象: 可以将复杂的对象状态存储到备忘录中,简化对象本身 🧘!

三、 备忘录模式的实现方式

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

  • 发起人(Originator): 创建备忘录,并使用备忘录恢复自身状态 🕹️。
  • 备忘录(Memento): 存储发起人的内部状态 💾。
  • 管理者(Caretaker): 负责保存备忘录,但不检查备忘录的内容 📦。

代码示例:

// 备忘录:游戏存档
class GameMemento {private int score; // 分数private int level; // 关卡public GameMemento(int score, int level) {this.score = score;this.level = level;}public int getScore() {return score;}public int getLevel() {return level;}
}// 发起人:游戏角色
class GameRole {private int score; // 分数private int level; // 关卡public GameRole(int score, int level) {this.score = score;this.level = level;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public int getLevel() {return level;}public void setLevel(int level) {this.level = level;}// 创建备忘录public GameMemento createMemento() {return new GameMemento(score, level);}// 从备忘录恢复状态public void restoreMemento(GameMemento memento) {this.score = memento.getScore();this.level = memento.getLevel();}// 显示游戏状态public void display() {System.out.println("当前分数:" + score + ",当前关卡:" + level);}
}// 管理者:存档管理器
class Caretaker {private GameMemento memento; // 备忘录public GameMemento getMemento() {return memento;}public void setMemento(GameMemento memento) {this.memento = memento;}
}// 客户端
public class Client {public static void main(String[] args) {GameRole gameRole = new GameRole(1000, 5); // 创建游戏角色gameRole.display(); // 显示游戏状态Caretaker caretaker = new Caretaker(); // 创建存档管理器caretaker.setMemento(gameRole.createMemento()); // 保存游戏存档gameRole.setScore(500); // 游戏失误,分数降低gameRole.setLevel(3); // 关卡降低gameRole.display(); // 显示游戏状态gameRole.restoreMemento(caretaker.getMemento()); // 读档gameRole.display(); // 显示游戏状态}
}

分析:

  • GameMemento 是备忘录,存储了游戏角色的分数和关卡。
  • GameRole 是发起人,可以创建备忘录,并使用备忘录恢复自身状态。
  • Caretaker 是管理者,负责保存备忘录。

输出结果:

当前分数:1000,当前关卡:5
当前分数:500,当前关卡:3
当前分数:1000,当前关卡:5

四、 备忘录模式的优缺点

优点:

  • 保存状态 💾!
  • 保护封装性 🔒!
  • 支持撤销 🔙!
  • 简化对象 🧘!

缺点:

  • 增加了存储成本(需要存储备忘录) 💰!
  • 管理备忘录可能会比较复杂 📦!

五、 备忘录模式的应用场景

  • 需要保存一个对象的内部状态,以便以后可以恢复: 就像你需要保存游戏存档,以便在失误后可以读档 🎮!
  • 需要支持撤销操作: 就像你需要支持游戏中的“悔棋”功能 🔙!
  • 需要在事务管理中实现回滚操作: 就像数据库事务需要支持回滚操作 🔄!
  • 需要在编辑器中实现撤销/重做功能: 就像 Word 编辑器需要支持撤销/重做功能 📝!

六、 总结

  • 备忘录模式就像给对象创建一个“存档点”,以便在需要的时候可以“读档重来”! 💾+🕹️
  • 优点是保存状态、保护封装性、支持撤销、简化对象! 👍
  • 缺点是增加存储成本、管理备忘录复杂! 👎
  • 适用于需要保存对象状态,并支持撤销操作的场景! 🎯

希望这篇文章能让你彻底理解备忘录模式! 💯 祝你学习愉快! 😄
看完请看:(二 十 三)趣学设计模式 之 解释器模式!

相关文章:

(二 十 二)趣学设计模式 之 备忘录模式!

目录 一、 啥是备忘录模式?二、 为什么要用备忘录模式?三、 备忘录模式的实现方式四、 备忘录模式的优缺点五、 备忘录模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,…...

交叉编译openssl及curl

操作环境:Ubuntu20.04 IDE工具:Clion2020.2 curl下载地址:https://curl.se/download/ openssl下载地址:https://openssl-library.org/source/old/index.html 直接交叉编译curl会报错找不到openssl,所以需要先交叉编…...

【每日八股】计算机网络篇(三):IP

目录 DNS 查询服务器的基本流程DNS 采用 TCP 还是 UDP,为什么?默认使用 UDP 的原因需要使用 TCP 的场景?总结 DNS 劫持是什么?解决办法?浏览器输入一个 URL 到显示器显示的过程?URL 解析TCP 连接HTTP 请求页…...

Gartner:数据安全平台DSP提升数据流转及使用安全

2025 年 1 月 7 日,Gartner 发布“China Context:Market Guide for Data Security Platforms”(《数据安全平台市场指南——中国篇》,以下简称指南),报告主要聚焦中国数据安全平台(Data Securit…...

从vue源码解析Vue.set()和this.$set()

前言 最近死磕了一段时间vue源码,想想觉得还是要输出点东西,我们先来从Vue提供的Vue.set()和this.$set()这两个api看看它内部是怎么实现的。 Vue.set()和this.$set()应用的场景 平时做项目的时候难免不会对 数组或者对象 进行这样的骚操作操作&#xff…...

深入浅出:UniApp 从入门到精通全指南

https://juejin.cn/post/7440119937644101684 uni-app官网 uniapp安卓离线打包流程_uniapp离线打包-CSDN博客 本文是关于 UniApp 从入门到精通的全指南,涵盖基础入门(环境搭建、创建项目、项目结构、编写运行)、核心概念与进阶知识&#x…...

DeepSeek未来发展趋势:开创智能时代的新风口

DeepSeek未来发展趋势:开创智能时代的新风口 随着人工智能(AI)、深度学习(DL)和大数据的飞速发展,众多创新型技术已经逐渐走向成熟,而DeepSeek作为这一领域的新兴力量,正逐步吸引越…...

阻塞队列的实现(线程案例)

一.什么是阻塞队列? 1.如果对于一个满的队列,还要把元素入队列,此时这个队列就会阻塞等待,一直阻塞到这个队列不满为止,从而把这个元素入队列! 2.如果对于一个空的队列,还要从队列拿出元素&…...

http status是什么?常见的http状态码指的是什么意思?

HTTP 状态码 HTTP 状态码(HTTP Status Code)是服务器在响应客户端请求时返回的一个三位数字代码,用于表示请求的处理结果。HTTP 状态码是 HTTP 协议的一部分,帮助客户端(如浏览器或应用程序)了解请求是否成…...

react组件分离,降低耦合

分离前 分离后...

【AI】AI白日梦+ChatGPT 三分钟生成爆款短视频

引言 随着人工智能(AI)技术的快速发展,AI在各个领域都展现出了强大的应用潜力。其中,自然语言处理技术的进步使得智能对话系统得以实现,而ChatGPT作为其中的代表之一,具有自动生成文本的能力,为…...

MYSQL的安装教程

mysql安装分为:普通安装和压缩包安装 压缩包安装很多会存在安装失败的情况,所以我这里就用了普通安装 一、官网下载安装包 www.mysql.com 点击DOWNLOADS: 进入社区版本下载: 点击最下面一行进行下载: 选择第二个离…...

深入解析 C# 中的泛型:概念、用法与最佳实践

C# 中的 泛型(Generics) 是一种强大的编程特性,允许开发者在不预先指定具体数据类型的情况下编写代码。通过泛型,C# 能够让我们编写更灵活、可重用、类型安全且性能优良的代码。泛型广泛应用于类、方法、接口、委托、集合等多个方…...

NUMA架构介绍

NUMA 架构详解 NUMA(Non-Uniform Memory Access,非统一内存访问) 是一种多处理器系统的内存设计架构,旨在解决多处理器系统中内存访问延迟不一致的问题。与传统的 UMA(Uniform Memory Access,统一内存访问…...

数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南

文章目录 数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南ChatGPTKimi腾讯元宝DeepSeek 数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南 产品隐私设置操作路径隐私协议ChatGPT…...

python爬虫:python中使用多进程、多线程和协程对比和采集实践

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. 多进程爬虫1.1 python多进程样例1.2 实现多进程爬虫2. 多线程爬虫2.1 python多线程样例2.2 实现多线程爬虫3. 协程爬虫3.1 python协程样例3.2 实现协程爬虫在网络爬虫中,为了提高抓取效率,常常需要使用多进程、多线…...

《OpenCV》—— dlib库

文章目录 dlib库是什么?OpenCV库与dlib库对比dlib库安装dlib——人脸应用实例——人脸检测dlib——人脸应用实例——人脸关键点定位dlib——人脸应用实例——人脸轮廓绘制 dlib库是什么? OpenCV库与dlib库对比 dlib库安装 dlib——人脸应用实例——人脸检…...

Linux搜索---find

find搜索 find 命令的核心功能是在指定的目录路径下,递归地搜索文件和目录,并且可以根据多种条件对搜索结果进行筛选,还能对符合条件的文件和目录执行特定操作。 一、基础语法结构 find [起始目录] [匹配条件] [执行操作] # 基本示例 find…...

python之爬虫入门实例

链家二手房数据抓取与Excel存储 目录 开发环境准备爬虫流程分析核心代码实现关键命令详解进阶优化方案注意事项与扩展 一、开发环境准备 1.1 必要组件安装 # 安装核心库 pip install requests beautifulsoup4 openpyxl pandas# 各库作用说明: - requests&#x…...

Blender常用快捷键的汇总

一、基础操作 全选/取消全选:A(全选)、AA(连续按两次A取消全选)复制物体:Shift D(复制后需点击确认位置)移动物体:G(按X/Y/Z可约束轴向移动)旋转…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言:多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...