备忘录模式(Memento)

备忘录模式是一种行为设计模式,在不破坏封装性的前提下,允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

Memento is a behavior design pattern. Without compromising encapsulation, 
it can reserve and restore of the previous state of an object, not exposing 
its implementation details.

结构设计

一个备忘录(memento)是一个对象,它存储另一个对象在某个瞬间的内部状态,而后者称为备忘录的原发器(originator)。当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。
原发器用描述当前状态的信息初始化备忘录。只有原发器可以向备忘录中存取信息,备忘录对其他的对象"不可见"。
备忘录模式包含如下角色:
Originator,原发器,可以生成自身状态的快照,也可以在需要时通过快照恢复自身状态。
Memento,备忘录,是原发器状态快照的值对象(value object)。通常做法是将备忘录设为不可变的,并通过构造函数一次性传递数据。
Caretaker,负责人,仅知道“何时”和“为何”捕捉原发器的状态,以及何时恢复状态。负责人通过保存备忘录栈来记录原发器的历史状态。 当原发器需要回溯历史状态时,
负责人将从栈中获取最顶部的备忘录, 并将其传递给原发器的恢复(restoration)方法。
备忘录模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下备忘录模式的实现。

// 1、原发器,支持读写自身状态,支持生成自身状态的快照,支持通过快照恢复自身状态
public class Originator {private String name;private String describe;public String getName() {return name;}public void setName(String name) {this.name = name;}public void setDescribe(String describe) {this.describe = describe;}public String getDescribe() {return this.describe;}public Memento save() {return new Memento(this, name, describe);}public void restore(Memento memento) {setName(memento.getName());setDescribe(memento.getDescribe());}
}//2、备忘录,是原发器状态快照的值对象
public class Memento {private String name;private String describe;private Originator originator;public Memento(Originator originator, String name, String describe) {this.originator = originator;this.name = name;this.describe = describe;}public String getName() {return this.name;}public String getDescribe() {return this.describe;}
}// 3、负责人,通过保存备忘录栈来记录原发器的历史状态。当原发器需要回溯历史状态时,负责人将从栈中获取最顶部的备忘录,并将其传递给原发器的恢复(restoration)方法
public class Caretaker {private Originator originator;private LinkedList<Memento> history;public Caretaker(Originator originator) {this.originator = originator;history = new LinkedList<>();}public void snapshot() {history.push(originator.save());}public void undo() {Memento lastMemento = history.pop();originator.restore(lastMemento);}
}// 4、客户端
public class MementoClient {public void test() {// (1) 创建原生器实例并设置状态Originator originator = new Originator();originator.setName("1");originator.setDescribe("one");// (2) 创建负责人实例Caretaker caretaker = new Caretaker(originator);// (3) 创建快照caretaker.snapshot();System.out.println("name is " + originator.getName() + " , " + "describe is " + originator.getDescribe());originator.setName("2");originator.setDescribe("two");caretaker.snapshot();System.out.println("name is " + originator.getName() + " , " + "describe is " + originator.getDescribe());// (4) 恢复上一个状态caretaker.undo();System.out.println("name is " + originator.getName() + " , " + "describe is " + originator.getDescribe());caretaker.undo();System.out.println("name is " + originator.getName() + " , " + "describe is " + originator.getDescribe());}
} 

适用场景

在以下情况下可以考虑使用备忘录模式:
(1) 当需要创建对象状态快照来恢复其之前的状态时,可以考虑使用备忘录模式。 备忘录模式允许复制对象中的全部状态(包括私有成员变量),并将其独立于对象进行保存。
尽管大部分人因为 “撤销” 这个用例才记得该模式,但其实它在处理事务(比如需要在出现错误时回滚一个操作)的过程中也必不可少。
(2) 当直接访问对象的成员变量、获取器或设置器将导致封装被突破时,可以考虑使用备忘录模式。备忘录让对象自行负责创建其状态的快照。任何其他对象都不能读取快照,这有效地保障了数据的安全性。

优缺点

备忘录模式有以下优点:
(1) 可以在不破坏对象封装情况的前提下创建对象状态快照。
(2) 可以通过让负责人维护原发器状态历史记录来简化原发器代码。
(3) 给用户提供了一种可恢复状态的机制,能够比较方便地回滚到某个历史状态。
但是该模式也存在以下缺点:
(1) 如果客户端过于频繁地创建备忘录,程序将消耗大量内存。
(2) 负责人必须完整跟踪原发器的生命周期,这样才能销毁弃用的备忘录。

参考

《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://refactoringguru.cn/design-patterns/memento 备忘录模式
https://www.runoob.com/design-pattern/memento-pattern.html 备忘录模式
https://www.cnblogs.com/adamjwh/p/11018268.html 简说设计模式——备忘录模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/55947.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医疗知识图谱问答——文本分类解析

前言 Neo4j的数据库构建完成后&#xff0c;现在就是要实现医疗知识的解答功能了。因为是初版&#xff0c;这里的问题解答不会涉及深度学习&#xff0c;目前只是一个条件查询的过程。而这个过程包括对问题的关键词拆解分类&#xff0c;然后提取词语和类型去图数据库查询&#xf…

Android安卓实战项目(8)---自行车fitting计算软件(源码在文末)

Android安卓实战项目&#xff08;8&#xff09;—自行车fitting计算软件&#xff08;源码在文末&#x1f415;&#x1f415;&#x1f415;&#xff09; 【bilibili演示地址】 https://www.bilibili.com/video/BV1eu4y1B7yA/?share_sourcecopy_web&vd_sourceb2e9b9ed746ac…

回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-BiGRU蛇群算法…

Typescript - 索引签名

目录 1&#xff0c;什么是索引签名1&#xff0c;js 中使用对象的属性2&#xff0c;ts 中的索引签名3&#xff0c;扩展索引签名定义的类型 2&#xff0c;与 Record 对比3&#xff0c;遇到的问题1&#xff0c;索引 key 的类型问题&#xff0c;keyof2&#xff0c;索引 key 的类型问…

【Element】el-cascader 级联选择器

ElementUI label 为空的不展示 将children设为undefined dg(list) {list.forEach(item > {item.label item.nameitem.value item.iditem.children item.childrenList.length ! 0 ? item.childrenList : undefinedif (item.children) {this.dg(item.children)}}) },第…

11. Redis基础知识

文章目录 一、概述二、数据类型STRINGLISTSETHASHZSET 三、数据结构字典跳跃表 四、使用场景计数器缓存查找表消息队列会话缓存分布式锁实现其它 五、Redis 与 Memcached数据类型数据持久化分布式内存管理机制 六、键的过期时间七、数据淘汰策略八、持久化RDB 持久化AOF 持久化…

HCIP VLAN--Hybrid接口

一、VLAN的特点 1、一个VLAN就是一个广播域&#xff0c;所以在同一个VLAN内部&#xff0c;计算机可以直接进行二层通信&#xff1b;而不同VLAN内的计算机&#xff0c;无法直接进行二层通信&#xff0c;只能进行三层通信来传递信息&#xff0c;即广播报文被限制在一个VLAN内。 …

护眼灯色温高好还是色温低好?教你如何挑选护眼台灯

随着人们对家庭环境艺术的重视&#xff0c;台灯因其摆设在桌案台几上的特殊地位&#xff0c;也要进求特有的装饰效果。家居用台灯开始逐新分流为工艺台灯和书写台灯两类。前者追求外观效果&#xff0c;将发展思路放在材质的创新、造型的求异上&#xff0c;以配合风格多样的家居…

如果网站的 Cookie 特别多特别大,会发生什么(一)

有没有想过&#xff0c;如果网站的 Cookie 特别多特别大&#xff0c;会发生什么情况&#xff1f; 不多说&#xff0c;马上来试验一下&#xff1a; for (i 0; i < 20; i) document.cookie i X.repeat(2000) 什么&#xff0c;网站居然报错了&#xff1f; 众所周知&am…

Spring MVC项目概述及创建

Spring MVC项目概述及创建 1.什么是Spring MVC Spring MVC是基于SevletAPI的原始Web框架。Spring MVC项目也叫做SpringWeb项目。 它是在springboot项目中引入了web框架&#xff0c;原本的spring项目不具备网络通信能力&#xff0c;而spring mvc允许http响应&#xff0c;当用…

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio构建SpringSecurity权限框架

1.Cloud Studio&#xff08;云端 IDE&#xff09;简介 Cloud Studio 是基于浏览器的集成式开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装&#xff0c;随时随地打开浏览器就能在线编程。 Clou…

边写代码边学习之LSTM

1. 什么是LSTM 长短期记忆网络 LSTM&#xff08;long short-term memory&#xff09;是 RNN 的一种变体&#xff0c;其核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径&#xff0c;让信息能在序列连中传递下去。你可以将其看作网络的“记忆”。理论上讲&a…