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

23种设计模式-备忘录(Memento)设计模式

文章目录

  • 一.什么是备忘录设计模式?
  • 二.备忘录模式的特点
  • 三.备忘录模式的结构
  • 四.备忘录模式的优缺点
  • 五.备忘录模式的 C++ 实现
  • 六.备忘录模式的 Java 实现
  • 七.总结

类图: 备忘录设计模式类图

一.什么是备忘录设计模式?

备忘录设计模式(Memento Pattern)是一种行为型设计模式,用于在不暴露对象实现细节的前提下,捕获并保存对象在某一时刻的状态,以便之后可以将其恢复到之前的状态。该模式的主要目标是保存对象的状态并在需要时进行状态回滚。

二.备忘录模式的特点

  1. 封装状态:将对象的内部状态存储在备忘录中,并且不让外部访问这些状态细节。
  2. 提供撤销功能:支持撤销操作,特别适合需要恢复到之前状态的场景。
  3. 降低耦合:发起者(Originator)与管理备忘录的角色(Caretaker)解耦。

三.备忘录模式的结构

  1. Originator(发起者):负责创建备忘录并恢复自身状态。
  2. Memento(备忘录):存储发起者的状态。
  3. 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));}
}

七.总结

 备忘录设计模式适用于需要保存对象状态并提供恢复功能的场景,比如文本编辑器、游戏存档等。通过将状态封装到备忘录中,备忘录模式实现了状态的透明保存与恢复,从而提升了系统的可维护性和灵活性。
应用场景:

  1. 文本编辑器:保存编辑状态,支持撤销和恢复操作。
  2. 游戏存档:保存玩家的游戏进度,并允许玩家恢复到之前的状态。
  3. 事务管理:数据库事务可以利用备忘录模式保存数据状态,实现事务回滚。

相关文章:

23种设计模式-备忘录(Memento)设计模式

文章目录 一.什么是备忘录设计模式&#xff1f;二.备忘录模式的特点三.备忘录模式的结构四.备忘录模式的优缺点五.备忘录模式的 C 实现六.备忘录模式的 Java 实现七.总结 类图&#xff1a; 备忘录设计模式类图 一.什么是备忘录设计模式&#xff1f; 备忘录设计模式&#xff08…...

搜维尔科技:Manus遥操作五指机械手专用手套惯性高精度虚拟现实

Manus遥操作五指机械手专用手套惯性高精度虚拟现实 搜维尔科技&#xff1a;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.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…...

JWT 过期后 自动刷新方案

JWT&#xff08;JSON Web Token&#xff09;广泛应用于现代 Web 开发中的认证与授权&#xff0c;它以无状态、灵活和高效的特点深受开发者欢迎。然而&#xff0c;JWT 的一个核心问题是 Token 过期后如何处理。本文将总结常见的解决方案&#xff0c;分析其优缺点&#xff0c;并帮…...

react-amap海量点优化

前言&#xff1a;高版本的react-amap 支持MassMarkers 组件用于一次性添加大量的标记点。本次优化的海量点是在低版本react-amap的基础上。官方推荐使用聚合useCluster属性来优化海量点的渲染。 直接附上代码&#xff1a; import React, { Component } from "react"…...

GRU(门控循环单元)详解

1️⃣ GRU介绍 前面介绍的LSTM可以有效缓解RNN的梯度消失问题&#xff0c;但是其内部结构比较复杂&#xff0c;因此衍生出了更加简化的GRU。GRU把输入门和遗忘门整合成一个更新门&#xff0c;并且合并了细胞状态和隐藏状态。于2014年被提出 2️⃣ 原理介绍 GRU的结构和最简单…...

【代码随想录|回溯算法排列问题】

491.非减子序列 题目链接. - 力扣&#xff08;LeetCode&#xff09; 这里和子集问题||很像&#xff0c;但是这里要的是非递减的子序列&#xff0c;要按照给的数组的顺序来进行排序&#xff0c;就是如果我给定的数组是[4,4,3,2,1]&#xff0c;如果用子集||的做法先进行排序得到…...

Azure Kubernetes Service (AKS)资源优化策略

针对Azure Kubernetes Service (AKS)的资源优化策略&#xff0c;可以从多个维度进行考虑和实施&#xff0c;以提升集群的性能、效率和资源利用率。以下是一些关键的优化策略&#xff1a; 一、 Pod资源请求和限制 设置Pod请求和限制&#xff1a;在YAML清单中为所有Pod设置CPU和…...

R语言 | 宽数据变成一列,保留对应的行名和列名

对应稀疏矩阵 转为 宽数据框&#xff0c;见 数据格式转换 | 稀疏矩阵3列还原为原始矩阵/数据框&#xff0c;自定义函数 df3toMatrix() 目的&#xff1a;比如查看鸢尾花整体的指标分布&#xff0c;4个指标分开&#xff0c;画到一个图中。每个品种画一个图。 1.数据整理&#…...

RTSP播放器EasyPlayer.js播放器在webview环境下,PC和安卓能够正常播放,IOS环境下播放器会黑屏无法播放

流媒体技术分为顺序流式传输和实时流式传输两种。顺序流式传输允许用户在下载的同时观看&#xff0c;而实时流式传输则允许用户实时观看内容。 流媒体播放器负责解码和呈现内容&#xff0c;常见的播放器包括VLC和HTML5播放器等。流媒体技术的应用场景广泛&#xff0c;包括娱乐…...

.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&#xff0c;因为其维护不力&#xff0c;并转向 Microsoft.AspNetCore.OpenApi。除了 Swashbuckle&am…...

c语言数据22数组使用

1.1数组分配的空间 int a[10]{1,2,3,4,5,6,7,8,9,10};//分配空间 元素类型大小int4*元素个数1040byte 元素之间空间连续 数组名代表数组首元素地址&#xff1b;a 取的是a[0]的地址&#xff1b;&a 是整个数组的地址 说明&#xff1a; 数组首元素地址&#xff1a; 0号元…...

深入理解TensorFlow中的形状处理函数

摘要 在深度学习模型的构建过程中&#xff0c;张量&#xff08;Tensor&#xff09;的形状管理是一项至关重要的任务。特别是在使用TensorFlow等框架时&#xff0c;确保张量的形状符合预期是保证模型正确运行的基础。本文将详细介绍几个常用的形状处理函数&#xff0c;包括get_…...

MySQL数据库3——函数与约束

一.函数 1.字符串函数 MySQL中内置了很多字符串函数&#xff0c;常用的几个如下&#xff1a; 使用方法&#xff1a; SELECT 函数名(参数);注意&#xff1a;MySQL中的索引值即下标都是从1开始的。 2.数值函数 常见的数值函数如下&#xff1a; 使用方法&#xff1a; SELECT…...

⾃动化运维利器 Ansible-Jinja2

Ansible-Jinja2 一、Ansible Jinja2模板背景介绍二、 JinJa2 模板2.1 JinJa2 是什么2.2 JinJa2逻辑控制 三、如何使用模板四、实例演示 按顺序食用&#xff0c;口味更佳 ( 1 ) ⾃动化运维利器Ansible-基础 ( 2 ) ⾃动化运维利器 Ansible-Playbook ( 3 ) ⾃动化运维利器 Ansible…...

博客文章怎么设计分类与标签

首发地址&#xff08;欢迎大家访问&#xff09;&#xff1a;博客文章怎么设计分类与标签 新网站基本上算是迁移完了&#xff0c;迁移之后在写文章的过程中&#xff0c;发现个人的文章分类和标签做的太混乱了&#xff0c;分类做的像标签&#xff0c;标签也不是特别的丰富&#x…...

FastDDS之DataSharing

目录 原理说明限制条件配置Data-Sharing delivery kindData-sharing domain identifiers最大domain identifiers数量共享内存目录 DataReader和DataWriter的history耦合DataAck阻塞复用 本文详细记录Fast DDS中Data Sharing的实现原理和代码分析。 DataSharing的概念&#xff1…...

计算机网络在线测试-概述

单项选择题 第1题 数据通信中&#xff0c;数据传输速率&#xff08;比特率&#xff0c;bps&#xff09;是指每秒钟发送的&#xff08;&#xff09;。 二进制位数 &#xff08;我的答案&#xff09; 符号数 字节数 码元数 第2题 一座大楼内的一个计算机网络系统&#xf…...

【MySQL】数据库必考知识点:查询操作全面详解与深度解剖

前言&#xff1a;本节内容讲述基本查询&#xff0c; 基本查询要分为两篇文章进行讲解。 本篇文章主要讲解的是表内删除数据、查询结果进行插入、聚合统计、分组聚合统计。 如果想要学习对应知识的可以观看哦。 ps:本篇内容友友们只要会创建表了就可以看起来了哦&#xff01;&am…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...