设计之禅——备忘录模式
时间:2022-07-24
本文章向大家介绍设计之禅——备忘录模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
引言
备忘录模式是非常简单的一种模式,应用场景非常广泛,如编辑器的ctrl + z、数据库事务的回滚、游戏的存档等等都符合该模式的思想——备份(比较疑惑为什么叫备忘录模式,叫备份模式不是更贴切么?)。
详解
备忘录模式就是将一个对象的内部状态保存到对象的外部,这样,在将来的任一时间点都可以恢复到之前的状态,让我们有后悔药可以吃。它包含了发起人(originator)、备忘录(memento)、负责人(caretaker)三个角色:
- 发起人:负责创建备份,将当前对象所需存储的状态保存到外部,并可以在需要时恢复备份。
- 备忘录:负责存储对象的内部状态。
- 负责人:用于保存备忘录以及将备忘录传递给其它对象,但不能直接访问操作备忘录对象的内部状态(保证封装性和安全性)。
模式的结构和定义都非常简单,下面就实现一个文本编辑器的“撤销”功能。
Coding
首先是编辑器对象,也就会发起人角色:
public class Editor {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Memento createMemento() {
return new Memento(this.content);
}
public void undo(Memento memento) {
this.content = memento.getContent();
}
}
备忘录对象:
public class Memento {
private String content;
public Memento(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
负责人,只提供保存和传递备忘录对象的方法,不能对备忘录内部状态进行修改(这是必须的,否则无法保证恢复的数据是最初的数据,备忘录模式还有什么意义?):
public class Caretaker {
private Stack<Memento> mementos = new Stack<>();
public void savePoint(Memento memento) {
mementos.push(memento);
}
public Memento getMemento() {
return mementos.pop();
}
}
最后我们来体验下这个强大的编辑器吧:
public static void main(String[] args) {
Editor editor = new Editor();
editor.setContent("1");
System.out.println("第一次修改内容:" + editor.getContent());
// 编辑内容并保存
Caretaker caretaker = new Caretaker();
caretaker.savePoint(editor.createMemento());
editor.setContent("2");
System.out.println("第二次修改后内容:" + editor.getContent());
caretaker.savePoint(editor.createMemento());
editor.setContent("3");
System.out.println("第三次次修改后内容:" + editor.getContent());
caretaker.savePoint(editor.createMemento());
editor.setContent("4");
System.out.println("第四次次修改后内容:" + editor.getContent());
editor.undo(caretaker.getMemento());
System.out.println("第一次恢复后的内容:" + editor.getContent());
editor.undo(caretaker.getMemento());
System.out.println("第二次恢复后的内容:" + editor.getContent());
editor.undo(caretaker.getMemento());
System.out.println("第三次恢复后的内容:" + editor.getContent());
}
输出如下:
第一次修改内容:1
第二次修改后内容:2
第三次次修改后内容:3
第四次次修改后内容:4
第一次恢复后的内容:3
第二次恢复后的内容:2
第三次恢复后的内容:1
这样我们就实现了一个单状态的备忘录模式,但在实际应用中,业务场景会复杂很多,我们可能会需要保存很多的状态,应该如何做呢?读者们可以自行思考一下,这里我就不展开了
总结
备忘录模式给我们提供了“后悔药”,让我们在需要时可以随时反悔,但是当记录的状态非常多时,就会占用大量的资源,因此在使用时需要设置合理的上限。
- 基于 vue2 + vuex 构建一个具有 45 个页面的大型单页面应用
- 深度解剖dubbo源码
- .NET Core采用的全新配置系统[6]: 深入了解三种针对文件(JSON、XML与INI)的配置源
- 基于 vue2 构建和后台真实交互的 管理系统
- ASP.NET MVC的Model元数据与Model模板:模板的获取与执行策略
- python3.6抓取100知乎用户头像详解(四)
- 从运营商小广告到HTTPS
- .NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]
- 区块链:为什么它不仅仅是比特币?
- Java Mail(二):JavaMail介绍及发送一封简单邮件
- ASP.NET MVC Controller激活系统详解:总体设计
- .NET Core采用的全新配置系统[7]: 将配置保存在数据库中
- Selenium3+Python3环境部署
- Java Mail(三):Session、Message详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux中把.c的文件编译成.so文件
- Ubuntu16.04 中 locate文件查找命令
- Ubuntu 16.04与Apache虚拟主机配置的步骤详解
- Linux删除目录下的文件的10种方法小结
- 利用Linux防火墙隔离本地欺骗地址的方法详解
- 视图在SQL中的作用是什么,它是怎样工作的?
- Linux命令行上如何使用日历详解
- 在Linux下修改和重置root密码的方法(超简单)
- 在Centos上搭建Maven中央仓库的方法
- 详解Ubuntu16.04启动器图标异常解决方法
- Linux(ubuntu)下实现增加/删除文件权限
- Vim中文件编码处理与重新打开乱码文件详解
- Linux常用命令mkdir详解
- CentOS6.5环境下使用rsync增量同步备份文件的方法
- Linux 搭建Git服务器的方法