设计模式——备忘录模式(Memento)

设计模式——备忘录模式(Memento)

server/2024/5/11 16:04:24/ 标签: 设计模式, 备忘录模式, java

备忘录模式(Memento Pattern),也称为快照模式或Token模式,是GoF(Gang of Four,四位设计模式专家)提出的23种设计模式之一,属于行为模式。该模式的主要目的是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在适当的时候能够恢复到原先的状态。

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

  1. Originator(发起人):负责创建一个备忘录(Memento),用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
  2. Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象;而Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
  3. Caretaker(管理者):负责保存备忘录Memento,但不能对Memento的内容进行访问或者操作。

备忘录模式的优点包括:

  • 封装性备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
  • 简化发起人:发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
  • 恢复机制:提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

然而,备忘录模式也有其缺点:

  • 资源消耗:如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
  • 存储空间未知:当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

以下是一个简单的备忘录模式(Memento Pattern)的Java代码示例。在这个示例中,我们有一个Originator类,它有一个内部状态,并可以创建和恢复其状态的备忘录。Memento类用于存储Originator的状态,而Caretaker类则负责保存和管理这些备忘录。

java">// 备忘录接口
interface Memento {// 这里可以定义一些方法来获取备忘录的状态
}// 具体的备忘录类
class OriginatorMemento implements Memento {private String state;public OriginatorMemento(String state) {this.state = state;}// 获取备忘录的状态(这里只是一个简单的getter方法)public String getState() {return state;}// 可能还有其他方法来设置状态,但在这个简单的例子中我们不需要
}// 发起人类
class Originator {private String state;// 创建一个备忘录并返回public Memento createMemento() {return new OriginatorMemento(this.state);}// 恢复备忘录中的状态public void restoreMemento(Memento memento) {this.state = ((OriginatorMemento) memento).getState();}// 设置发起人状态public void setState(String state) {this.state = state;}// 获取发起人状态public String getState() {return state;}
}// 管理者类
class Caretaker {private Memento memento;// 保存备忘录public void setMemento(Memento memento) {this.memento = memento;}// 获取备忘录public Memento getMemento() {return memento;}
}// 客户端代码
public class Client {public static void main(String[] args) {Originator originator = new Originator();Caretaker caretaker = new Caretaker();// 设置发起人状态originator.setState("State 1");System.out.println("Current state: " + originator.getState());// 保存当前状态到备忘录caretaker.setMemento(originator.createMemento());// 修改发起人状态originator.setState("State 2");System.out.println("Current state: " + originator.getState());// 恢复之前保存的备忘录中的状态originator.restoreMemento(caretaker.getMemento());System.out.println("Restored state: " + originator.getState());}
}

在这个例子中,Originator类有一个state字段,它可以通过setState方法设置,并通过getState方法获取。createMemento方法创建一个OriginatorMemento对象,其中包含当前的staterestoreMemento方法接受一个Memento对象,并将其中的状态设置回Originatorstate字段。

Caretaker类用于保存Memento对象,并在需要时提供访问。

Client类中,我们创建了一个Originator和一个Caretaker对象,并演示了如何设置、保存和恢复Originator的状态。


http://www.ppmy.cn/server/39753.html

相关文章

在Linux系统上安装Conda安装教程

在Linux系统上安装Conda安装教程 在Linux系统上安装Conda,特别是Miniconda(Conda的一个小型版本,包含conda、Python和一些必要的库,非常适合快速开始使用)的步骤如下: 1. 准备工作 打开终端:首…

Linux--进程间的通信--进程池

进程间的通信–匿名管道 进程池的概念 进程池是一种将多个进程组织起来以执行特定任务的机制。它由多个预先创建好的资源进程和一个管理进程组成。这些资源进程被管理进程负责分配和调度,用于处理任务。 当有新的任务提交时,管理进程会从进程池中取出一…

简单的Python HTML 输出

1、问题背景 一名初学者在尝试将 Python 脚本输出到网页上时遇到了一些问题。他当前使用 Python 和 HTML 进行开发,并且遇到了以下问题: 担心自己的代码过于复杂,尤其是 WebOutput() 函数。希望通过 JavaScript 使用 HTML 模板文件更新数据。…

【算法刷题day50】Leetcode:309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费

文章目录 Leetcode 309. 买卖股票的最佳时机含冷冻期解题思路代码总结 Leetcode 714. 买卖股票的最佳时机含手续费解题思路代码总结 草稿图网站 java的Deque Leetcode 309. 买卖股票的最佳时机含冷冻期 题目:309. 买卖股票的最佳时机含冷冻期 解析:代码…

Hive优化(1)——分桶采样

分桶(Bucketing) 分桶是将数据按照某个字段的哈希值进行分组存储的一种技术。它的原理是将数据按照指定字段的哈希值分成固定数量的桶,将每条记录分配到对应的桶中。分桶可以帮助优化特定类型的查询,例如连接查询和聚合操作&…

常见比较实用的Chrome命令/扩展程序

文章目录 一、Chrome命令二、Chrome操作三、Chrome扩展程序 一、Chrome命令 Chrome浏览器提供了一系列实用的内部命令和URL,这些命令可以帮助用户快速访问浏览器的各种功能和设置。以下是一些实用的Chrome命令: 查看所有支持的命令: 直接在…

6.Nginx

Nginx反向代理 将前端发送的动态请求有Nginx转发到后端服务器 那为何要多一步转发而不直接发送到后端呢? 反向代理的好处: 提高访问速度(可以在nginx做缓存,如果请求的是同样的接口地址,这样就不用多次请求后端&#…

WP All Import Pro插件下载 - 一键导入,无限可能

在当今快节奏的数字时代,网站内容的更新和管理是每个网站管理员和开发者的日常工作。但是,传统的手动更新方法不仅耗时,而且容易出错。现在,有了WP All Import Pro,这一切都将改变。 WP All Import Pro 是一款专为Wor…

刺客信条提示找不到emp.dll,无法继续执行代码的8个有效解决方法

遇到游戏提示缺少emp.dll文件的问题时,不必过于焦虑,这个问题相对常见且有多种解决方案。以下是一些实用的心得和步骤来帮助你修复这个问题: 在计算机世界里,动态链接库(Dynamic Link Library,简称DLL&…

在Python中使用OpenCV读取图片的路径有中文,会读取失败。

用OpenCV的imread读取图片,如果图片路径有中文,读取会失败。这个问题只会在Python中出现,在C中不会出现。 这个问题也很好避免,因为OpenCV可以直接从内存读入图片,所以只需要把含有中文路径的图片先读入内存&#xff…

小程序内使用web-view组件嵌套H5页面,当H5页面更换了内容后,小程序里的h5页面不更新

这个问题是由于小程序缓存了H5的内容造成的&#xff0c;可以在H5链接后面拼接个参数&#xff0c;加上时间戳可做用于H5的版本号&#xff0c;这样每次访问都可以全新的链接展示内容避免缓存&#xff0c;代码如下wxml&#xff1a; <view> <web-view src"{{urlpath…

无人零售,重塑购物新纪元

在这个快节奏的时代&#xff0c;科技的每一次跃进都在悄无声息地改变着我们的生活方式。而今&#xff0c;无人零售正以雷霆之势&#xff0c;颠覆传统购物模式&#xff0c;为我们带来前所未有的便捷与智能体验。想知道无人零售如何彻底改变我们的购物方式吗&#xff1f;跟随我&a…

KMeans,KNN,Mean-shift算法的学习

1.KMeans算法是什么&#xff1f; 在没有标准标签的情况下&#xff0c;以空间的k个节点为中心进行聚类&#xff0c;对最靠近他们的对象进行归类。 2.KMeans公式&#xff1a; 2. 1.关键分为三个部分&#xff1a; 1.一开始会定义n个中心点&#xff0c;然后计算各数据点与中心点…

初识Java

目录 Java语言概述 Java是什么 Java语言重要性 语言广泛使用程度 工作领域 在校招中的岗位需求 互联网的发展史 java集成开发环境 Java语言的特性 Java语言概述 Java是什么 Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语法 Java语…

C语言——文件操作

大家好&#xff0c;今天和大家介绍C语言中文件操作的有关内容&#xff0c;欢迎大家观阅&#xff0c;记得三连支持一下哦&#xff01; 一、文件 在学习文件操作之前我们先来了解一下什么是文件。 1.什么是文件&#xff1f; 磁盘上的文件就是文件。 在编程中我们通常把文件按…

视图地一些笔记

1. 创建视图&#xff08;CREATE VIEW&#xff09;时&#xff0c;通常不会输出任何结果集。它只是一种定义逻辑视图的方式&#xff0c;在数据库中保存一个查询定义。要查看视图中的内容&#xff0c;你需要使用 SELECT 语句查询该视图。例如&#xff0c;如果你创建了名为 new_us…

Git详解之五:分布式Git

为了便于项目中的所有开发者分享代码&#xff0c;我们准备好了一台服务器存放远程 Git 仓库。经过前面几章的学习&#xff0c;我们已经学会了一些基本的本地工作流程中所需用到的命令。接下来&#xff0c;我们要学习下如何利用 Git 来组织和完成分布式工作流程。 特别是&#…

Java并发编程之锁的艺术:面试与实战指南(四)

Java并发编程之锁的艺术&#xff1a;面试与实战指南&#xff08;四&#xff09; 文章目录 Java并发编程之锁的艺术&#xff1a;面试与实战指南&#xff08;四&#xff09;前言二十七、什么是AQS&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff1f;它在Java并发包中…

Element快速上手!

Element是饿了么公司前端团队开发的一套基于Vue的组件库&#xff0c;用于快速构建网页~ 官网链接&#xff1a; Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.elem…

OKHTTP 3.12.0 以后版本 headers 中不可携带中文

今天遇到的报错&#xff1a; java.lang.llegalArgumentException: Unexpected char 0x957f at 0 in x-brand value: 电视堆栈 okhttp3.Headers.checkValue(Headers.java:272) okhttp3.Headers$Builder.add(Headers.java:312) okhttp3.Request$Builder.addHeader(Request.iava:…