备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)


意图
结构

- 备忘录模式通过引入备忘录Memento记录对象的内部状态
- 引入管理员CareTaker对备忘录进行管理
- 控制访问--原发器Originator与备忘录对象进行交互,其他所有地方都只是获取传递,不更改设置Memento的状态
代码示例
一个简单的快照实现
快照信息保存在备忘录Memento中
通过管理员CareTaker进行保管
package memento.simple;
/**
* 业务逻辑类,也就是我们需要备份的对象
* 内部拥有state属性,用来表示快照需要保存的状态数据
*/
public class Originator {
private Integer state;
/**
* 创建快照备份
* @return
*/
public Memento createMemento() {
return new Memento(state);
}
/**
* 恢复快照
* @param memento
*/
public void recovery(Memento memento) {
state = memento.getState();
} public Integer getState() {
return state;
} public void setState(Integer state) {
this.state = state;
} @Override
public String toString() {
final StringBuilder sb = new StringBuilder("Originator{");
sb.append("state=").append(state);
sb.append('}');
return sb.toString();
}
}
package memento.simple;
/**
* 备忘录类用来保存业务逻辑对象的状态(原发器)
* 备忘录类的属性要参考原发器的设计,确定需要保存哪些数据信息
* 此处我们以state为演示
* 备忘录类提供了getter和setter方法
*/
public class Memento {
private Integer state;
Memento(Integer state) {
this.state = state;
} public Integer getState() {
return state;
} public void setState(Integer state) {
this.state = state;
}
}
package memento.simple;
/**
* 管理员类,内部拥有一个memento,可以设置和获取这个属性
*/
public class CareTaker { private Memento memento;
public Memento getMemento() {
return memento;
} public void setMemento(Memento memento) {
this.memento = memento;
}
}
package memento.simple;
public class Test { public static void main(String[] args) { //创建业务逻辑对象,设置状态信息
Originator originator = new Originator();
originator.setState(2); //快照
Memento memento = originator.createMemento();
CareTaker careTaker = new CareTaker();
careTaker.setMemento(memento); System.out.println("初始时状态: " + originator.toString()); originator.setState(3);
System.out.println("更新状态后: " + originator.toString()); originator.setState(8);
System.out.println("更新状态后: " + originator.toString()); originator.setState(6);
System.out.println("更新状态后: " + originator.toString()); originator.recovery(careTaker.getMemento());
System.out.println("恢复状态后: " + originator.toString());
}
}

- Memento备忘录对来自Originator的修改开放(比如上面的Originator可以创建Memento)
- Memento备忘录对来自CareTaker的修改开放(上面示例中,仅仅传递Memento,不曾访问内部细节)

内部类方式重构
package memento;
public interface MementoInterface {
}
package memento;
/**
* 业务逻辑类,也就是我们需要备份的对象 内部拥有state属性,用来表示快照需要保存的状态数据
*/
public class Originator {
private Integer state;
/**
* 创建快照备份返回标记接口,以使外界不能操作备忘录
*/
public Memento createMemento() {
return new Memento(state);
}
/**
* 恢复快照,接受MementoInterface类型参数 使用时强转为内部类Memento
*/
public void recovery(MementoInterface memento) {
state = ((Memento) memento).getState();
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
/**
* 私有内部类,实现MementoInterface接口,标记接口 用以外界交互,达到对外界close的效果
*/
private class Memento implements MementoInterface {
private Integer state; Memento(Integer state) {
this.state = state;
} public Integer getState() {
return state;
} public void setState(Integer state) {
this.state = state;
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Originator{");
sb.append("state=").append(state);
sb.append('}');
return sb.toString();
}
}
package memento;
/**
* 管理员类,内部拥有一个 MementoInterface,可以设置和获取这个属性
*/
public class CareTaker {
private MementoInterface memento;
public MementoInterface getMemento() {
return memento;
}
public void setMemento(MementoInterface memento) {
this.memento = memento;
}
}


时序图

- 客户端程序对原发器Originator进行状态设置
- 客户端程序对原发器进行快照创建
- 客户端程序对快照进行保存
- 客户端程序获得快照
- 客户端程序根据快照进行状态恢复
重构小结
- 借助于私有内部类实现了对外界的封闭
- 将负责人管理员CareTaker与Memento进行解耦,通过抽象MementoInterface进行连接
形式变换
package memento.refactor1;
/**
* 管理员类,内部拥有一个 MementoInterface,可以设置和获取这个属性
*/
public class CareTaker { private MementoInterface memento;
private Originator originator; CareTaker(Originator originator) {
this.originator = originator;
} /**
* 创建快照,借助于内部的Originator
*/
public MementoInterface createMemento() {
return originator.createMemento();
} /**
* 恢复快照,借助于内部的Originator
*/
public void recovery(MementoInterface memento) {
originator.recovery(memento);
}
public MementoInterface getMemento() {
return memento;
}
public void setMemento(MementoInterface memento) {
this.memento = memento;
}
}
public static void main(String[] args) {
Memento memento = originator.createMemento();
originator.recovery(originator.recovery();
}
与命令模式的联系
总结
备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)的更多相关文章
- Java设计模式(十二) 策略模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...
- 解释器模式 Interpreter 行为型 设计模式(十九)
解释器模式(Interpreter) 考虑上图中计算器的例子 设计可以用于计算加减运算(简单起见,省略乘除),你会怎么做? 你可能会定义一个工具类,工具类中有N多静态方法 比如定义了两个 ...
- 命令模式 Command 行为型 设计模式(十八)
命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...
- 桥接模式 桥梁模式 bridge 结构型 设计模式(十二)
桥接模式Bridge Bridge 意为桥梁,桥接模式的作用就像桥梁一样,用于把两件事物连接起来 意图 将抽象部分与他的实现部分进行分离,使得他们都可以独立的发展. 意图解析 依赖倒置原 ...
- C#设计模式之二十二备忘录模式(Memento Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就是对某个对象的状态进行保 ...
- C#设计模式之二十二备忘录模式(Memeto Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第十个模式,该模式是[备忘录模式],英文名称是:Memento Pattern.按老规矩,先从名称上来看看这个模式,个人的最初理解就 ...
- Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式
前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...
- Java设计模式之十二 ---- 备忘录模式和状态模式
前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...
- C#设计模式之十二享元模式(Flyweight)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第六个模式,该模式是[享元模式],英文名称是:Flyweight Pattern.还是老套路,先从名字上来看看."享元"是不是可以这样 ...
随机推荐
- Redis in .NET Core 入门:(5) Sorted SET
第1篇:https://www.cnblogs.com/cgzl/p/10294175.html 第2篇 String:https://www.cnblogs.com/cgzl/p/10297565. ...
- python输出彩色字体
Python终端如何输出彩色字体 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ES ...
- java代码之美(11)---java代码的优化
java代码的优化 随着自己做开发时间的增长,越来越理解雷布斯说的: 敲代码要像写诗一样美.也能理解有一次面试官问我你对代码有洁癖吗? 一段好的代码会让人看就像诗一样,也像一个干净房间会让人看去很舒服 ...
- 基于百度AI开放平台的人脸识别及语音合成
基于百度AI的人脸识别及语音合成课题 课题需求 (1)人脸识别 在Web界面上传人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口识别人脸特征,接收平台返回的人员年龄.性别.颜 ...
- 模板方法模式 Template method 行为型 设计模式(二十六)
模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为 ...
- vivo4.0系统怎么不ROOT激活Xposed框架的教程
在越来越多应用室的引流,或业务操作中,大多数需要使用安卓的强大Xposed框架,前几天,我们应用室采购了一批新的vivo4.0系统,大多数都是基于7.0以上系统,大多数不能够刷入Root的su权限,即 ...
- Android利用RecyclerView实现列表倒计时效果
最近面试时,面试官问了一个列表倒计时效果如何实现,然后脑袋突然懵的了O(∩_∩)O,现在记录一下. 运行效果图 实现思路 实现方法主要有两个: 1.为每个开始倒计时的item启动一个定时器,再做更新i ...
- SQL Server 2008R2 :远程调用失败 的解决方法(全部方法)
SQL 中远程调用失败的原因 1.服务里面的启动权限未能启动,修改sql对应的服务进程权限就可以了 2.是因为VS 和SQL 起冲突了,数据库找不到访问地址导致的.解决的办法很简单,就是卸载掉多余的版 ...
- SQLsever存储过程分页查询
使用存储过程实现分页查询,SQL语句如下: USE [DatebaseName] --数据库名 GO /****** Object: StoredProcedure [dbo].[Pagination ...
- 跟我一起学opencv 第二课之图像的掩膜操作
1.掩膜(mask)概念 用选定的图像,图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程.用于覆盖的特定图像或物体称为掩模或模板.光学图像处理中,掩模可以足胶片,滤光片等 ...