【设计模式】—— 备忘录模式Memento
时间:2022-04-22
本文章向大家介绍【设计模式】—— 备忘录模式Memento,主要内容包括模式意图、模式结构、生活中的设计模式、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
模式意图
这个模式主要是想通过一个对象来记录对象的某种状态,这样有利于在其他需要的场合进行恢复。
该模式还有跟多可以扩展的地方,比如可以记录多个时间的状态,每个角色都有可以扩展的空间,完全看业务场景而定。
应用场景
1 保存对象某一时刻的状态
2 避免直接暴露接口,破坏封装性
模式结构
Originator 是备忘录的发起者,记录状态的对象
class Originator{
private String state;
public Memento ceateMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public String getState(){
return this.state;
}
public void setState(String state){
this.state = state;
System.out.println("Current state = "+this.state);
}
}
Memento 备忘录角色,通常用于保存某种状态
class Memento{
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Caretaker 备忘录的负责人,负责在恰当的时机,进行状态的恢复
class Caretaker{
private Memento memento;
public Memento retrieveMemento(){
return this.memento;
}
public void saveMemento(Memento memento){
this.memento = memento;
}
}
全部代码
package com.xingoo.test.design.memento;
class Originator{
private String state;
public Memento ceateMemento() {
return new Memento(state);
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public String getState(){
return this.state;
}
public void setState(String state){
this.state = state;
System.out.println("Current state = "+this.state);
}
}
class Memento{
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
class Caretaker{
private Memento memento;
public Memento retrieveMemento(){
return this.memento;
}
public void saveMemento(Memento memento){
this.memento = memento;
}
}
public class Client {
private static Originator o = new Originator();
private static Caretaker c = new Caretaker();
public static void main(String[] args) {
o.setState("On");
//记录状态
c.saveMemento(o.ceateMemento());
//更改状态
o.setState("Off");
//更新状态
o.restoreMemento(c.retrieveMemento());
}
}
运行结果
Current state = On
Current state = Off
生活中的设计模式
最近看了会 恶魔奶爸,挺扯淡的漫画。不过看到其中的女仆,让我想起了这种备忘录模式。
主人在有什么重要的事情时,都会交给女仆记着,规定的时间在提醒自己。
下面的主人就有一件很重要的事情,就是陪亲爱的小丽去看电影,于是他弄了一个笔记本,记录下了这个信息。女仆拿到笔记本,并在预先商量好的时间提醒主人。这里的笔记本就是上面的备忘录对象Memento,而这个模式中,主人就是备忘录的发起者,女仆是负责人。
这里涉及到的备忘录是属于【白箱】的,也就是说,备忘录中的信息,可以被发起人和负责人看到。还有一种是【黑箱】的,主要是用了一种内部类继承这个备忘录对象,这样外部的负责人就得不到真正备忘录中的具体信息。
下面看下具体的实现,主人的代码如下:
1 class Master{
2 private String info;
3 public String getInfo() {
4 return info;
5 }
6 public void setInfo(String info) {
7 this.info = info;
8 }
9 public Note createNote(String info){
10 return new Note(info);
11 }
12 public void action(Note note){
13 this.info = note.getInfo();
14 System.out.println("主人看到笔记,记起了 "+ this.info);
15 }
16 public void toDo(){
17 System.out.println("****主人正在..."+info);
18 }
19 }
女仆的代码如下:
1 class Maid{
2 private Note note;
3 public Note readNote(){
4 System.out.println("女仆拿到笔记本");
5 return this.note;
6 }
7 public void writeNote(Note note){
8 System.out.println("女仆写笔记");
9 this.note = note;
10 }
11 }
备忘录的代码如下:
1 class Note{
2 private String info;
3 public Note(String info) {
4 this.info = info;
5 }
6 public void setInfo(String info){
7 this.info = info;
8 System.out.println("写笔记!");
9 }
10 public String getInfo(){
11 System.out.println("读笔记!");
12 return info;
13 }
14 }
全部代码:
1 package com.xingoo.test.design.memento;
2 class Note{
3 private String info;
4 public Note(String info) {
5 this.info = info;
6 }
7 public void setInfo(String info){
8 this.info = info;
9 System.out.println("写笔记!");
10 }
11 public String getInfo(){
12 System.out.println("读笔记!");
13 return info;
14 }
15 }
16 class Master{
17 private String info;
18 public String getInfo() {
19 return info;
20 }
21 public void setInfo(String info) {
22 this.info = info;
23 }
24 public Note createNote(String info){
25 return new Note(info);
26 }
27 public void action(Note note){
28 this.info = note.getInfo();
29 System.out.println("主人看到笔记,记起了 "+ this.info);
30 }
31 public void toDo(){
32 System.out.println("****主人正在..."+info);
33 }
34 }
35 class Maid{
36 private Note note;
37 public Note readNote(){
38 System.out.println("女仆拿到笔记本");
39 return this.note;
40 }
41 public void writeNote(Note note){
42 System.out.println("女仆写笔记");
43 this.note = note;
44 }
45 }
46 public class LifeWithMaid {
47 public static void main(String[] args) {
48 Master master = new Master();
49 Maid maid = new Maid();
50 //主人想起了要做的事情
51 maid.writeNote(master.createNote("晚上6点,配小丽看电影"));
52 //主人忙其他的事情
53 master.setInfo("睡觉吃饭打豆豆!");
54 master.toDo();//主人正在做什么?
55 //时间到了,女仆提醒主人
56 master.action(maid.readNote());
57 master.toDo();//主人正在做什么?
58 }
59 }
运行结果
女仆写笔记
****主人正在...睡觉吃饭打豆豆!
女仆拿到笔记本
读笔记!
主人看到笔记,记起了 晚上6点,配小丽看电影
****主人正在...晚上6点,配小丽看电影
- 白话推荐系统——从原理到实践,还有福利赠送!
- 基于Spring Boot的Logback日志轮转配置
- Java程序员的日常—— Spring Boot单元测试
- Windows下TensorFlow安装指南(图文版)
- 20120918-双向链表类定义《数据结构与算法分析》
- 20120918-LIST类定义《数据结构与算法分析》
- Scala入门学习笔记四--List使用
- 20120918-向量实现《数据结构与算法分析》
- hadoop 1.x环境搭建
- JavaScript二维码生成——qrcode.js
- Spark中文指南(入门篇)-Spark编程模型(一)
- HDOJ 1008
- 单链表反转的分析及实现
- 在windows下使用eclipes连接linux下的Hadoop集群
- 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 数组属性和方法
- 分布式锁(数据库、Redis、ZK)拍了拍你
- 贷款违约预测-Task3 特征工程
- 用SQL代替DSL查询ElasticSearch怎样?
- 面试造飞机:面对Redis持久化连环Call,你还顶得住吗?
- 体验spring-boot-devtools热部署,流畅且不失强大,Jrebel呢?
- 贷款诈骗 x 摸版0day + 实战预警脚本
- 你不知道的 Linux 使用技巧
- 一文详解 Websocket 的前世今生
- 实例 | 教你用Python写一个电信客户流失预测模型
- OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测
- 看了这个总结,其实 Matplotlib 可视化,也没那么难!
- 使用OpenCV进行模糊检测(拉普拉斯算子)
- 利用opencv对图像进行长曝光
- 总说手机没有“好壁纸”,Python一次性抓取500张“美女”图片,够不够用!
- KEDA发布2.0(Beta)|来一个伸缩测试