Java设计模式学习记录-备忘录模式
前言
这次要介绍的是备忘录模式,也是行为模式的一种 。现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了。那么备忘录模式又是什么样子的呢?是不是和手机上的备忘录一样呢?下面来介绍一下。
备忘录模式
概念介绍
备忘录模式是指在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。简单的来说就是平时玩的通关游戏,第一次前进了5步,第二次前进时踩到便便了,然后要回到之前的进度。例如下图结构:

举例
我们还是用一个小例子来简单介绍一下备忘录模式,在玩一个步骤游戏时,每走一步时步数都加一,遇到道具可以快速走几步,或者减几步。用备忘录模式的思想来实现这个逻辑,就是如下代码。
游戏类
/**
* 游戏
*/
@Data
public class Game { /**
* 玩家走的步数
*/
private int playerStep; /**
* 备份游戏
* @return
*/
public GameMemento createGameMemento(){
return new GameMemento(playerStep);
} /**
* 开始玩游戏
*/
public void play(){
playerStep = 0;
} /**
* 恢复备份
* @param gameMemento
*/
public void restore(GameMemento gameMemento){
this.playerStep = gameMemento.getPlayerSteps();
}
}
备份
/**
* 备份
*/
@Getter
public class GameMemento {
/** 步数 */
private int playerSteps; /**
* 备份步数
* @param playerSteps
*/
public GameMemento(int playerSteps){
this.playerSteps = playerSteps;
} }
备份信息管理类
/**
* 备份信息管理类
*/
public class Caretaker {
/** 备份 */
private GameMemento gameMemento;
/** 恢复备份 */
public GameMemento retrieveMemento(){
return this.gameMemento;
}
/** 保存备份 */
public void saveMemento(GameMemento gameMemento){
this.gameMemento = gameMemento;
}
}
测试
public class Player {
public static void main(String[] args) {
Game game = new Game();
System.out.println("游戏开始,捡到滑板,前进10步");
game.setPlayerStep(10);
//备份当前状态
System.out.println("备份当前状态");
GameMemento gameMemento = game.createGameMemento();
Caretaker caretaker = new Caretaker();
caretaker.saveMemento(gameMemento);
System.out.println("备份完成");
game.play();
System.out.println("踩到便便了,当前步数为:"+game.getPlayerStep());
System.out.println("还原到之前一步");
game.restore(caretaker.retrieveMemento());
System.out.println("恢复完成,当前玩家步数是:"+game.getPlayerStep());
}
}
运行结果
游戏开始,捡到滑板,前进10步
备份当前状态
备份完成
踩到便便了,当前步数为:0
还原到之前一步
恢复完成,当前玩家步数是:10
上面的这个例子使用了lombok插件的注解例如:@Getterhe@Data所以少写了getter和setter方法。看完了这个小例子,大概应该知道备忘录模式是个什么逻辑了吧,有点类似咱们平时知道的事务回滚的机制。下面还是分析一下,备忘录模式都是由哪些部分组成的。
备忘录模式结构
结构图如下

备忘录模式的构成角色如下所示。
原发器类(Originator):创建一个备忘录对象,使用备忘录存储它的内部状态。
负责人类(CareTaker):负责保存好备忘录对象,不能检查或操作备忘录的内容。
备忘录类(Memento):将原发器的内部状态存储起来,原发器根据需要决定备忘录存储原发器的哪些内部状态。
总结
优点
1、它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
2、备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。
缺点
资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。
适用场景
1、保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。
2、防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。
想了解更多的设计模式请查看Java设计模式学习记录-GoF设计模式概述。
Java设计模式学习记录-备忘录模式的更多相关文章
- Java设计模式学习记录-模板方法模式
前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Java设计模式学习记录-解释器模式
前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...
- Java设计模式学习记录-命令模式
前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...
- Java设计模式学习记录-外观模式
前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...
- Java设计模式学习记录-桥接模式
前言 这次介绍结构型设计模式中的第二种模式,桥接模式. 使用桥接模式的目的就是为了解耦,松散的耦合更利于扩展,但是会增加相应的代码量和设计难度. 桥接模式 桥接模式是为了将抽象化与实现化解耦,让二者可 ...
- Java设计模式学习记录-代理模式
代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...
- Java设计模式学习记录-建造者模式
前言 今天周末,有小雨,正好也不用出门了,那就在家学习吧,经过了两周的面试,拿到了几个offer,但是都不是自己很想去的那种,要么就是几个人的初创小公司,要么就是开发企业内部系统的这种传统开发,感觉这 ...
随机推荐
- 软件光栅器实现(二、VS和PS的运作,法线贴图,切空间的计算)
二.软件光栅器的VS和PS的输入.输出和运作,实现法线贴图效果的版本.转载请注明出处. 这里介绍的VS和PS是实现法线映射的版本,本文仅介绍实现思路,并给出代码供参考.切空间计算.光照模型等相关公式不 ...
- 初学者必看的文章:在VM12中安装 RedHat RHEL7.2 系统的详细步骤:看我如何操纵RHEL系统
一.开始安装 1)新建虚拟机 RHEL7.2 2)成功引导系统--开机出现此画面 Install Red Hat EnterpriseLinux 7.2 安装RHLE7.2 操作系统 Test th ...
- 安装完Ubuntu后通过shell脚本一键安装软件
安装完Ubuntu后通过shell脚本一键安装软件 以下代码中#是单行注释 :<<! ! 是多行注释. 运行的时候需要把多行注释去掉. 比如把以下代码保存为install.sh, 那么在终 ...
- 学习Python第五天
今天咱们讲一下元组,hash,字典,元组是数据类型其中之一 元组的特性为有序的,不可变的,但是如果其中有可变元素,这些可变元组还是可以改变的,代码如下: 元组的写法:name = (‘roy’,‘al ...
- 通配符的匹配很全面, 但无法找到元素 'xxxxxxxx'
首先,一般配置通配符之前,你都会有如下xml头吧 <beans xmlns="http://www.springframework.org/schema/beans" xml ...
- Hibernate知识总结(一)
一.ORM ORM的全称是Object/Relation Mapping,即对象/关系映射,可以将其理解成一种规范,它概述了这类框架的基本特征:完成面向对象的编程语言到关系数据库的映射.可以把ORM看 ...
- 使用HttpClient发送Get/Post请求 你get了吗?
HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议 ...
- Python中使用PyCharm为函数及参数增加注释
在函数名中键入数遍光标,左上角亮起小灯泡,点击小灯泡 选中第二行内容 在"""后添加函数注释,以及参数注释 然后再引用函数时,选中函数,Ctrl q 即可显示函数以及参 ...
- 性能调优之Mapping
Mapping层级的调优可能会花费时间,但是性能调优的效果确实非常显著的 优化Target,Source之后,可以调优Mapping 通常的方法是尽可能减少组件及组件的字段间不必要的连线 即尽可能用最 ...
- 测试工具之Fiddler
Fiddler是一款很好的抓包分析工具,里面有很多小功能,这里介绍常用功能 Fiddler下载地址: https://www.telerik.com/download/fiddler 下载完成后,直接 ...