23种设计模式-备忘录(Memento)设计模式
文章目录
- 一.什么是备忘录设计模式?
- 二.备忘录模式的特点
- 三.备忘录模式的结构
- 四.备忘录模式的优缺点
- 五.备忘录模式的 C++ 实现
- 六.备忘录模式的 Java 实现
- 七.总结
类图: 备忘录设计模式类图
一.什么是备忘录设计模式?
备忘录设计模式(Memento Pattern)是一种行为型设计模式,用于在不暴露对象实现细节的前提下,捕获并保存对象在某一时刻的状态,以便之后可以将其恢复到之前的状态。该模式的主要目标是保存对象的状态并在需要时进行状态回滚。
二.备忘录模式的特点
- 封装状态:将对象的内部状态存储在备忘录中,并且不让外部访问这些状态细节。
- 提供撤销功能:支持撤销操作,特别适合需要恢复到之前状态的场景。
- 降低耦合:发起者(Originator)与管理备忘录的角色(Caretaker)解耦。
三.备忘录模式的结构
- Originator(发起者):负责创建备忘录并恢复自身状态。
- Memento(备忘录):存储发起者的状态。
- Caretaker(管理者):负责保存和恢复备忘录。

四.备忘录模式的优缺点
- 优点:
- 提供了一种状态恢复机制。
- 发起者的内部状态对外部透明。
- 缺点:
- 可能需要大量的存储空间,尤其是需要存储大量状态时。
- 如果对象状态过于复杂,可能会增加备忘录的维护成本。
五.备忘录模式的 C++ 实现
#include <iostream>
#include <string>
#include <vector>
using namespace std;// 备忘录类
class Memento {
private:string state;
public:Memento(const string& s) : state(s) {}string GetState() const { return state; }
};// 发起者类
class Originator {
private:string state;
public:void SetState(const string& s) {state = s;cout << "Set state to: " << state << endl;}string GetState() const { return state; }Memento* CreateMemento() const {return new Memento(state);}void SetMemento(Memento* memento) {state = memento->GetState();cout << "Restored state to: " << state << endl;}
};// 管理者类
class Caretaker {
private:vector<Memento*> mementos;
public:void SaveMemento(Memento* memento) {mementos.push_back(memento);}Memento* GetMemento(int index) const {if (index >= 0 && index < mementos.size()) {return mementos[index];}return nullptr;}~Caretaker() {for (Memento* m : mementos) {delete m;}}
};int main() {Originator originator;Caretaker caretaker;originator.SetState("State1");caretaker.SaveMemento(originator.CreateMemento());originator.SetState("State2");caretaker.SaveMemento(originator.CreateMemento());originator.SetState("State3");// 恢复到之前的状态originator.SetMemento(caretaker.GetMemento(0));originator.SetMemento(caretaker.GetMemento(1));return 0;
}
六.备忘录模式的 Java 实现
import java.util.ArrayList;
import java.util.List;// 备忘录类
class Memento {private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}// 发起者类
class Originator {private String state;public void setState(String state) {this.state = state;System.out.println("Set state to: " + state);}public String getState() {return state;}public Memento createMemento() {return new Memento(state);}public void setMemento(Memento memento) {this.state = memento.getState();System.out.println("Restored state to: " + state);}
}// 管理者类
class Caretaker {private List<Memento> mementos = new ArrayList<>();public void saveMemento(Memento memento) {mementos.add(memento);}public Memento getMemento(int index) {if (index >= 0 && index < mementos.size()) {return mementos.get(index);}return null;}
}public class MementoPatternDemo {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();originator.setState("State1");caretaker.saveMemento(originator.createMemento());originator.setState("State2");caretaker.saveMemento(originator.createMemento());originator.setState("State3");// 恢复到之前的状态originator.setMemento(caretaker.getMemento(0));originator.setMemento(caretaker.getMemento(1));}
}
七.总结
备忘录设计模式适用于需要保存对象状态并提供恢复功能的场景,比如文本编辑器、游戏存档等。通过将状态封装到备忘录中,备忘录模式实现了状态的透明保存与恢复,从而提升了系统的可维护性和灵活性。
应用场景:
- 文本编辑器:保存编辑状态,支持撤销和恢复操作。
- 游戏存档:保存玩家的游戏进度,并允许玩家恢复到之前的状态。
- 事务管理:数据库事务可以利用备忘录模式保存数据状态,实现事务回滚。
相关文章:
23种设计模式-备忘录(Memento)设计模式
文章目录 一.什么是备忘录设计模式?二.备忘录模式的特点三.备忘录模式的结构四.备忘录模式的优缺点五.备忘录模式的 C 实现六.备忘录模式的 Java 实现七.总结 类图: 备忘录设计模式类图 一.什么是备忘录设计模式? 备忘录设计模式(…...
搜维尔科技:Manus遥操作五指机械手专用手套惯性高精度虚拟现实
Manus遥操作五指机械手专用手套惯性高精度虚拟现实 搜维尔科技:Manus遥操作五指机械手专用手套惯性高精度虚拟现实...
MySql面试题.运维面试题之五
《(全国)MySQL数据库DBA测试题-第1套》 卷面总分 题号 单选题 多选题 判断题 100 题分 42 40 18 得分 一、单选题(每题3分,共计42分;得分____) 1. 二进制rpm包安装的mysql数据库,默认的数据文件存放在如下哪个目录里? A、/usr/local/mysql B、/tmp/ C、/var/lib/my…...
小程序-基于java+SpringBoot+Vue的小区服务管理系统设计与实现
项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:…...
JWT 过期后 自动刷新方案
JWT(JSON Web Token)广泛应用于现代 Web 开发中的认证与授权,它以无状态、灵活和高效的特点深受开发者欢迎。然而,JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案,分析其优缺点,并帮…...
react-amap海量点优化
前言:高版本的react-amap 支持MassMarkers 组件用于一次性添加大量的标记点。本次优化的海量点是在低版本react-amap的基础上。官方推荐使用聚合useCluster属性来优化海量点的渲染。 直接附上代码: import React, { Component } from "react"…...
GRU(门控循环单元)详解
1️⃣ GRU介绍 前面介绍的LSTM可以有效缓解RNN的梯度消失问题,但是其内部结构比较复杂,因此衍生出了更加简化的GRU。GRU把输入门和遗忘门整合成一个更新门,并且合并了细胞状态和隐藏状态。于2014年被提出 2️⃣ 原理介绍 GRU的结构和最简单…...
【代码随想录|回溯算法排列问题】
491.非减子序列 题目链接. - 力扣(LeetCode) 这里和子集问题||很像,但是这里要的是非递减的子序列,要按照给的数组的顺序来进行排序,就是如果我给定的数组是[4,4,3,2,1],如果用子集||的做法先进行排序得到…...
Azure Kubernetes Service (AKS)资源优化策略
针对Azure Kubernetes Service (AKS)的资源优化策略,可以从多个维度进行考虑和实施,以提升集群的性能、效率和资源利用率。以下是一些关键的优化策略: 一、 Pod资源请求和限制 设置Pod请求和限制:在YAML清单中为所有Pod设置CPU和…...
R语言 | 宽数据变成一列,保留对应的行名和列名
对应稀疏矩阵 转为 宽数据框,见 数据格式转换 | 稀疏矩阵3列还原为原始矩阵/数据框,自定义函数 df3toMatrix() 目的:比如查看鸢尾花整体的指标分布,4个指标分开,画到一个图中。每个品种画一个图。 1.数据整理&#…...
RTSP播放器EasyPlayer.js播放器在webview环境下,PC和安卓能够正常播放,IOS环境下播放器会黑屏无法播放
流媒体技术分为顺序流式传输和实时流式传输两种。顺序流式传输允许用户在下载的同时观看,而实时流式传输则允许用户实时观看内容。 流媒体播放器负责解码和呈现内容,常见的播放器包括VLC和HTML5播放器等。流媒体技术的应用场景广泛,包括娱乐…...
.NET周刊【11月第3期 2024-11-17】
国内文章 .NET 9使用Scalar替代Swagger https://www.cnblogs.com/netry/p/18543378/scalar-an-alternative-to-swagger-in-dotnet-9 .NET 9 移除了 Swashbuckle.AspNetCore,因为其维护不力,并转向 Microsoft.AspNetCore.OpenApi。除了 Swashbuckle&am…...
c语言数据22数组使用
1.1数组分配的空间 int a[10]{1,2,3,4,5,6,7,8,9,10};//分配空间 元素类型大小int4*元素个数1040byte 元素之间空间连续 数组名代表数组首元素地址;a 取的是a[0]的地址;&a 是整个数组的地址 说明: 数组首元素地址: 0号元…...
深入理解TensorFlow中的形状处理函数
摘要 在深度学习模型的构建过程中,张量(Tensor)的形状管理是一项至关重要的任务。特别是在使用TensorFlow等框架时,确保张量的形状符合预期是保证模型正确运行的基础。本文将详细介绍几个常用的形状处理函数,包括get_…...
MySQL数据库3——函数与约束
一.函数 1.字符串函数 MySQL中内置了很多字符串函数,常用的几个如下: 使用方法: SELECT 函数名(参数);注意:MySQL中的索引值即下标都是从1开始的。 2.数值函数 常见的数值函数如下: 使用方法: SELECT…...
⾃动化运维利器 Ansible-Jinja2
Ansible-Jinja2 一、Ansible Jinja2模板背景介绍二、 JinJa2 模板2.1 JinJa2 是什么2.2 JinJa2逻辑控制 三、如何使用模板四、实例演示 按顺序食用,口味更佳 ( 1 ) ⾃动化运维利器Ansible-基础 ( 2 ) ⾃动化运维利器 Ansible-Playbook ( 3 ) ⾃动化运维利器 Ansible…...
博客文章怎么设计分类与标签
首发地址(欢迎大家访问):博客文章怎么设计分类与标签 新网站基本上算是迁移完了,迁移之后在写文章的过程中,发现个人的文章分类和标签做的太混乱了,分类做的像标签,标签也不是特别的丰富&#x…...
FastDDS之DataSharing
目录 原理说明限制条件配置Data-Sharing delivery kindData-sharing domain identifiers最大domain identifiers数量共享内存目录 DataReader和DataWriter的history耦合DataAck阻塞复用 本文详细记录Fast DDS中Data Sharing的实现原理和代码分析。 DataSharing的概念࿱…...
计算机网络在线测试-概述
单项选择题 第1题 数据通信中,数据传输速率(比特率,bps)是指每秒钟发送的()。 二进制位数 (我的答案) 符号数 字节数 码元数 第2题 一座大楼内的一个计算机网络系统…...
【MySQL】数据库必考知识点:查询操作全面详解与深度解剖
前言:本节内容讲述基本查询, 基本查询要分为两篇文章进行讲解。 本篇文章主要讲解的是表内删除数据、查询结果进行插入、聚合统计、分组聚合统计。 如果想要学习对应知识的可以观看哦。 ps:本篇内容友友们只要会创建表了就可以看起来了哦!&am…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
游戏开发中常见的战斗数值英文缩写对照表
游戏开发中常见的战斗数值英文缩写对照表 基础属性(Basic Attributes) 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...
使用python进行图像处理—图像滤波(5)
图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值,以达到平滑(去噪)、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算,…...
更新 Docker 容器中的某一个文件
🔄 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法,适用于不同场景。 ✅ 方法一:使用 docker cp 拷贝文件到容器中(最简单) 🧰 命令格式: docker cp <…...
