【设计模式|行为型】备忘录模式(Memento Pattern)
说明
备忘录模式是一种行为型设计模式,通过捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在需要时恢复对象到原先的状态。备忘录模式包含三个核心角色:。
- 发起人(Originator):负责创建一个备忘录,并记录当前对象的内部状态到备忘录中。
- 备忘录(Memento):负责存储发起人对象的内部状态,提供给发起人对象恢复内部状态的方法。
- 负责人(Caretaker):负责保存备忘录,可以使用备忘录来回滚对象的状态。
备忘录模式的核心思想是将对象的状态保存在一个独立的对象中,以便以后恢复。通过使用备忘录模式,我们可以轻松地实现对象状态的保存和恢复,同时也提高了系统的可维护性和扩展性。
优点
- 它提供了一种可以在不破坏封装性的情况下恢复对象状态的方法。
- 它简化了发起人对象的设计,避免了复杂的状态管理。
- 它可以在不影响客户端的情况下实现对象的历史记录和撤销操作。
缺点
- 需要消耗一定的内存空间来存储备忘录对象。
- 如果发起人对象的状态非常庞大,那么备忘录对象的存储和恢复操作可能会很昂贵。
使用场景
- 需要保存和恢复对象状态的场景,例如游戏中的存档功能、文档编辑器的撤销和恢复功能等。
- 需要提供对象的历史记录和撤销功能的场景,例如文本编辑器中的编辑历史记录、Web浏览器中的前进和后退功能等。
示例
下面以一个游戏存档的例子来说明备忘录模式的实现。
首先,我们定义游戏类Game,其中包含当前游戏的状态信息和对状态进行修改和恢复的方法:
public class Game {private String level;private int score;public Game(String level, int score) {this.level = level;this.score = score;}public String getLevel() {return level;}public void setLevel(String level) {this.level = level;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public void printStatus() {System.out.println("当前游戏状态:level=" + level + ", score=" + score);}// 创建备忘录public Memento createMemento() {return new Memento(level, score);}// 从备忘录中恢复状态public void restoreMemento(Memento memento) {this.level = memento.getLevel();this.score = memento.getScore();}
}
然后,我们定义备忘录类Memento,用于存储游戏状态:
public class Memento {private String level;private int score;public Memento(String level, int score) {this.level = level;this.score = score;}public String getLevel() {return level;}public int getScore() {return score;}
}
最后,我们定义管理者类Caretaker,用于保存游戏状态的备忘录,并支持回溯和恢复操作:
import java.util.Stack;public class Caretaker {private Stack<Memento> mementoStack = new Stack<>();// 保存当前状态public void save(Game game) {mementoStack.push(game.createMemento());}// 回溯到上一个状态public void undo(Game game) {if (!mementoStack.isEmpty()) {game.restoreMemento(mementoStack.pop());}}// 恢复到最初状态public void reset(Game game) {mementoStack.clear();game.setLevel("简单");game.setScore(0);}
}
现在,我们可以创建游戏对象、备忘录对象和管理者对象,进行游戏状态的保存、回溯和恢复:
public class MementoExample {public static void main(String[] args) {// 创建游戏对象Game game = new Game("简单", 0);// 创建管理者对象Caretaker caretaker = new Caretaker();// 保存当前状态caretaker.save(game);// 改变游戏状态game.setLevel("普通");game.setScore(100);// 保存当前状态caretaker.save(game);// 改变游戏状态game.setLevel("困难");game.setScore(200);// 保存当前状态caretaker.save(game);// 回溯到上一个状态caretaker.undo(game);game.printStatus(); // 当前游戏状态:level=普通, score=100// 回溯到最初状态caretaker.reset(game);game.printStatus(); // 当前游戏状态:level=简单, score=0}
}
现在,我们可以创建游戏对象、备忘录对象和管理者对象,进行游戏状态的保存、回溯和恢复:
当前游戏状态:level=普通, score=100
当前游戏状态:level=简单, score=0
相关文章:
【设计模式|行为型】备忘录模式(Memento Pattern)
说明 备忘录模式是一种行为型设计模式,通过捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在需要时恢复对象到原先的状态。备忘录模式包含三个核心角色:。 发起人(Originator):负责…...
Redis与其他缓存解决方案(如Memcached)的区别是什么?
Redis和其他缓存解决方案(如Memcached)在设计理念、功能和特点上有一些区别,以下是它们的主要区别: 数据类型支持:Redis支持多种数据类型(如字符串、哈希表、列表、集合、有序集合等)࿰…...
《面试1v1》Kafka的ack机制
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...
基于双 STM32+FPGA 的桌面数控车床控制系统设计
桌 面数控 设 备 对 小 尺寸零件加工在成 本 、 功 耗 和 占 地 面 积等方 面有 着 巨 大 优 势 。 桌 面数控 设 备 大致 有 3 种 实 现 方 案 : 第 一种 为 微 型 机 床搭 配 传统 数控系 统 , 但 是 桌 面数控 设 备 对 成 本 敏感 ; 第二 种 为 基 于 PC…...
ES-5-进阶
单机 & 集群 单台 Elasticsearch 服务器提供服务,往往都有最大的负载能力,超过这个阈值,服务器 性能就会大大降低甚至不可用,所以生产环境中,一般都是运行在指定服务器集群中 配置服务器集群时,集…...
Java面试准备篇:全面了解面试流程与常见问题
文章目录 1.1 Java面试概述1.2 面试流程和注意事项1.3 自我介绍及项目介绍1.4 常见面试问题 在现代职场中,面试是求职过程中至关重要的一环,特别是对于Java开发者而言。为了帮助广大Java开发者更好地应对面试,本文将提供一份全面的Java面试准…...
Go语言进阶语法八万字详解,通俗易懂
文章目录 File文件操作FileInfo接口权限打开模式File操作文件读取 I/O操作io包 文件复制io包下的Read()和Write()io包下的Copy()ioutil包总结 断点续传Seeker接口断点续传 bufio包bufio包原理Reader对象Writer对象 bufio包bufio.Readerbufio.Writer ioutil包ioutil包的方法示例…...
Apache RocketMQ 远程代码执行漏洞(CVE-2023-37582)
漏洞简介 Apache RocketMQ是一款低延迟、高并发、高可用、高可靠的分布式消息中间件。CVE-2023-37582 中,由于对 CVE-2023-33246 修复不完善,导致在Apache RocketMQ NameServer 存在未授权访问的情况下,攻击者可构造恶意请求以RocketMQ运…...
Kotlin Multiplatform 使用 CocoaPods 创建多平台分发库
Kotlin Multiplatform 支持直接创建Framework 方式和使用CocoaPods 方式创建Framework。 1、不同之处在于创建的时候需要选择不同的方式。 2、使用CocoaPods 方式还需要在 build.gradle(.kts) 文件中添加内容 在build.gradle(.kts) 文件中添加完成后,执行一下文件。…...
前端食堂技术周刊第 92 期:VueConf 2023、TypeChat、向量数据库、Nuxt 服务器组件指南
美味值:🌟🌟🌟🌟🌟 口味:整颗牛油果酸奶 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 大家好,我是童欧巴。欢迎来到前端食堂技术周刊,我们先…...
用C语言构建一个手写数字识别神经网络
(原理和程序基本框架请参见前一篇 "用C语言构建了一个简单的神经网路") 1.准备训练和测试数据集 从http://yann.lecun.com/exdb/mnist/下载手写数字训练数据集, 包括图像数据train-images-idx3-ubyte.gz 和标签数据 train-labels-idx1-ubyte.…...
vue关闭ESlint
在 vue.config.js里边写上这一句代码 lintOnsave:false写完后重启一下项目...
测试开发人员如何进行局部探索性测试?一张图告诉你
我们都知道全局探索性测试的漫游测试法,也知道局部探索性测试可以从用户输入、状态、代码路径、用户数据和执行环境测试着手点。 那么,如果我们能够获取开发代码,我们怎么从代码入手,进行具体的局部探索性测试呢? 简单…...
CentOS 8 上安装 Nginx
Nginx是一款高性能的开源Web服务器和反向代理服务器,以其轻量级和高效能而广受欢迎。在本教程中,我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1:更新系统 在安装任何软件之前,让我们先更新系统的软件包列表和已安…...
【c语言进阶】字符函数和字符串函数知识总结
字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strnca…...
DB2实现正则表达式
DB2实现正则表达式 功能描述 db2 11.1 及以上版本支持正则表达式,但是db2 10.5及以下版本不支持正则表达式,需要手工创建正则表达式函数。 安装与卸载步骤 README.txt2010-07-30IBM IMTE - Project AvalancheAuthor: Alexandre GrancherThis file des…...
CASS数据带属性转GIS的shp数据教程
一、数据:DWG文件中含有JZD(宗地层),JZP(界址点层),其中JZP中含有界址点号,实现JZD层转成ZD的shp数据;JZP转成JZD点的shp数据,并带出界址点号。 二、实现原理…...
Jenkins配置自动化构建的几个问题
在创建构建任务时,填写git远程仓库地址时,出现以下报错 解决此报错先排查一下linux机器上的git版本 git --version 如果git 版本过低,可能会导致拉取失败,此时需要下载更高的git版本。 参考 Git安装 第二个解决办法报错信息中…...
ubuntu 命令调节显示器亮度
1.显示器名字 xrandr -q | grep " connected" HDMI-0 connected primary 1920x108000 (normal left inverted right x axis y axis) 527mm x 297mm DP-4 connected 1920x108019200 (normal left inverted right x axis y axis) 527mm x 297mm 2.调节亮度 xrandr --ou…...
打卡力扣题目七
#左耳听风 ARST 打卡活动重启# 目录 一、题目 二、解题方法一 三、解题方法二 关于 ARTS 的释义 —— 每周完成一个 ARTS: ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 ● Share:…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
