文档章节

Memento模式

ruyees
 ruyees
发布于 2014/10/05 11:47
字数 1323
阅读 22
收藏 1

一、Memento模式的目的:

memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态.

二、Memento模式的简单例子:

下面的例子来源于Jdon网站的《GoF设计模式系列》的《Memento模式》,虽然简单却形象地表明了Memento模式的应用

 

 

package memento;

import java.io.File;

public class Originator {
	
	private int number; 
	private File file = null;
	
	public Originator(){
		
	}
	
	// 创建一个Memento,将自身作为参数传入
	public Memento getMemento(){
		return new Memento(this);
	}
	
	//从Memento中取出保存的数据,恢复为原始状态
	public void setMemento(Memento m){
		number = m.getNumber();
		file = m.getFile();
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}	
}

 

 

 

package memento;

import java.io.File;
import java.io.Serializable;

public class Memento implements Serializable {
	
	private int number;
	private File file = null;
	
	public Memento(Originator o){
		this.number = o.getNumber();
		this.file = o.getFile();
	}

	public int getNumber() {
		return this.number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

	public File getFile() {
		return this.file;
	}

	public void setFile(File file) {
		this.file = file;
	}
	
	
}

 

 

三、Memento模式的特点:

在需要提供保存、恢复对象状态的类中,必须提供两个方法:

.保存对象当前状态方法:将对象自身(this)作为参数传入,创建备忘录。
.恢复对象之前状态的方法:取出备忘录/接收一个备忘录对象,从中获取对象之前的状态

模式的缺点是耗费大,如果内部状态很多,再保存一份,无意要浪费大量内存.

注意:Memento模式保存的是操作前对象的状态,而不是操作后对象的状态;否则就没办法做恢复了

 

 

 

一、“Mementor”模式和“堆栈”的结合-“GUI界面撤销功能”的实现

·当用户在面板中拖动一个组件到编辑区时,应用程序为编辑区创建一个备忘录,并把它加入到一个堆栈中(注意此时备忘录中包含的是操作前的状态,而非操作后的状态)

·当用户单击“撤销”按钮时,应用程序就将堆栈顶部的备忘录弹出,然后将编辑区恢复为该备忘录所记录的状态

当可视化应用程序启动后,首先向空的堆栈中压入一个初始的空备忘录,并且保证绝对不会将该备忘录从栈中弹出,从而确保该栈的顶部总是有一个有效的备忘录。当栈中仅包含一个备忘录的时候,应用程序应当禁用“撤销”按钮

 

二、“Mementor”模式和“Observer”模式的结合-“通知式恢复”

在某些情况下,我们希望为GUI组件注册一些监听器,当组件的状态发生改变时,可以通知所有对它感兴趣的监听器,这种情况我们可以用“Observer”模式来实现。

还是以我们上面的例子来说:假如用户从面板中拖动一个组件到编辑区后,有几个监听器对它感兴趣,并且采取了相应的操作,现在用户单击了“撤销”按钮,那么我们应该把这个事件通知所有监听器,告诉他们必须恢复之前所有的状态。这种情况就可以把两种模式结合起来使用:

·当对象被创建时,激活并为该对象注册监听器(观察着),监听器创建一个初始化备忘录,保存编辑区的原始信息
·当对象(被观察着)被销毁(用户单击“撤销”按钮时),向所有注册的监听器发送信息
·监听器(观察者)接收到信息,从备忘录中取出编辑区信息的备忘录,恢复当前编辑区的状态

 

三、“Mementor”模式和“Observer”模式、“责任链”模式的结合-“链式通知恢复”

在上面我们提到了将“Mementor”模式和“Observer”模式结合起来达到到“通知式恢复”的效果,考虑下面一个情况:

如果我们在安装一个软件或执行一个长时间、多次交互的情况,加入用户在最后一个操作中选择了“取消”操作,我们应该怎么做呢?

我的想法是在为每一次操作创建一个备忘录,并将其放在“责任链”上,当最后用户选择取消时,沿着这条“责任链”一个个通知观察者,由观察者取出备忘录,执行恢复工作。

注意:这个方法和第二个方法有点区别:第二个方法不管恢复的顺序,而第三种方法适合讲究恢复顺序的情况,例如前面提到的软件安装的撤销。

 

四、“Mementor”模式和“Flyweight”模式的结合:减少相同对象的拷贝

用于保存对象状态的“备忘录”对象,必须拥有一份和被保存对象相同的属性拷贝。

对于“备忘录”有可能导致内存消耗过大的情况,如果对象中的属性是“公用的”(即多个对象可以共享一个属性),那么我们可以考虑采用“享元模式”,减少相同属性对象的创建。但是这个方法对于属性多为运行时确定的情况作用不大。

 

 

 

本文转载自:http://zuoqiang.iteye.com/blog/744024

共有 人打赏支持
ruyees
粉丝 3
博文 71
码字总数 0
作品 0
深圳
产品经理
设计模式--备忘录模式

备忘录模式(memento): 备忘录模式更确切的描述应该是"备份-恢复"模式。 示例: 备忘录模式测试类MementoTest.java 原始类Original.java 存储备忘录的类Storage.java 备忘录类Memento.java...

有钱有爱
2016/04/09
17
0
23种设计模式(15):备忘录模式

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的...

LCZ777
2014/07/10
0
0
设计模式(行为型模式)——备忘录模式(Memento)

本章讲讲第三类和第四类。 备忘录模式(Memento) 主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,...

小风89
2016/07/21
12
0
iOS设计模式---备忘录模式

备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 Originator(原发器):记录当前时刻的内部状态,负责定...

TonyGo
2015/08/13
0
0
23种设计模式总结(四)

备忘录模式 要点:一个Original类,一个 Memento 类,一个Storage类,Original可以创建一个Memento 的实例,用来保存自己的某些状态,Storage用来保存Memento ,其实某些情况下Storage类可用...

大胖和二胖
2016/11/29
9
0

没有更多内容

加载失败,请刷新页面

加载更多

js 操作cookie

var cookie = {// 设置cookie方法set:function(key, val, time){// 获取当前时间var date = new Date();// 将date设置为n天以后的时间var expiresDays = time;//...

小丶二
10分钟前
0
0
限制root远程登录 su和sudo命令

9月21日任务 3.7 su命令 3.8 sudo命令 3.9 限制root远程登录 对于Linux而言,权限的重要性毋庸置疑!对于普通用户而言无法执行那些只有root用户才能有效的命令,导致工作无法有效进行; 系统...

robertt15
11分钟前
0
0
MQTT协议的初浅认识之通讯级别和持久会话

背景 这是我最近了解MQTT协议的最后一部分内容了,MQTT协议里面的QOS和Keep Alive是两个比较重要的内容。QOS的设置,直接影响了订阅客户端与中间件之间的消息交互行为。而Keep Alive直接影响...

亚林瓜子
13分钟前
1
0
calc

width: calc(100% - 30px); 特别注意:减号左右空格,均不能去掉。 width: calc(100% - 30px);

柴高八斗之父
22分钟前
0
0
Spring Cloud Gateway全局过滤器GlobalFilter:返回消息和重定向

Spring Cloud Gateway的全局过滤器GlobalFilter,顾名思义,声明后会对所有的请求生效,可以用来做权限控制,这里简单记录一下拦截到非法请求后如何返回自定义信息和将请求重定向到指定URL。...

夜雨寄北09
24分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部