博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA中的备忘录模式实例教程
阅读量:5945 次
发布时间:2019-06-19

本文共 2681 字,大约阅读时间需要 8 分钟。

备忘录模式是一种行为模式。备忘录模式用于保存对象当前状态,并且在之后可以再次使用此状态。备忘录模式实现的方式需要保证,被保存的对象状态不能被对象从外部访问,目的为了被保存的这些对象状态的完整性。

备忘录模式通过两个对象实现:Originator以及Caretaker。Originator类代表了其状态能够被存储并被用于恢复之前的状态,它使用内部类保存对象的状态。此内部类就被叫做备忘录,注意此类是私有的,它不能被其他对象访问。

Caretaker是一个帮助类,它的职责就是通过备忘录帮助Originator存储当前状态或者恢复重建其之前的状态。因为备忘录是Originator的私有类,Caretaker不能访问它,因此它作为一个对象被存储在caretaker中。

现实中最好的例子是文本编辑器,它任何时候都存在已经输入的数据,并且可以使用回退功能恢复之前的存储(写作)状态。我们将实现相同功能并且提供一个任何时候都把输入、存在内容到文件中的工具集,此外,我们也能恢复上一个存储(写作)的状态。为了简单,此处没用更实用任何写入数据到文件的IO操作。

Originator类

package com.journaldev.design.memento;public class FileWriterUtil {	private String fileName;	private StringBuilder content;	public FileWriterUtil(String file){		this.fileName=file;		this.content=new StringBuilder();	}	@Override	public String toString(){		return this.content.toString();	}	public void write(String str){		content.append(str);	}	public Memento save(){		return new Memento(this.fileName,this.content);	}	public void undoToLastSave(Object obj){		Memento memento = (Memento) obj;		this.fileName= memento.fileName;		this.content=memento.content;	}	private class Memento{		private String fileName;		private StringBuilder content;		public Memento(String file, StringBuilder content){			this.fileName=file;			//notice the deep copy so that Memento and FileWriterUtil content variables don't refer to same object			this.content=new StringBuilder(content);		}	}}

注意备忘录的内部类及其保存及恢复方法。现在实现Caretaker类

Caretaker类

package com.journaldev.design.memento;public class FileWriterCaretaker {	private Object obj;	public void save(FileWriterUtil fileWriter){		this.obj=fileWriter.save();	}	public void undo(FileWriterUtil fileWriter){		fileWriter.undoToLastSave(obj);	}}

注意caretaker对象包含了整个对象形式的存储状态,因此它既不能修改被保存对象又对其结构未知。

备忘录测试类

完整一个简单地测试程序

package com.journaldev.design.memento;public class FileWriterClient {	public static void main(String[] args) {		FileWriterCaretaker caretaker = new FileWriterCaretaker();		FileWriterUtil fileWriter = new FileWriterUtil("data.txt");		fileWriter.write("First Set of Data\n");		System.out.println(fileWriter+"\n\n");		// lets save the file		caretaker.save(fileWriter);		//now write something else		fileWriter.write("Second Set of Data\n");		//checking file contents		System.out.println(fileWriter+"\n\n");		//lets undo to last save		caretaker.undo(fileWriter);		//checking file content again		System.out.println(fileWriter+"\n\n");	}}

上述程序的输出如下:

First Set of DataFirst Set of DataSecond Set of DataFirst Set of Data

此模式简单易实现,但是需要注意的是备忘录类只能被Originator对象访问。在客户端程序中,使用caretaker对象完成保存或恢复originator对象的状态。

另外,如果Originator对象有一些属性不是不可变的,我们需要使用深拷贝或者克隆来避免数据的完整性问题。使用序列化来取得备忘录模式的实现不失为一般方法,而不是为每一个对象创建一个自己的备忘录实现。

此模式的缺点是, 如果Originator对象非常巨大,那么备忘录对象的大小也会被相应增大,因而需要更多的内存空间。

  • 转载自 
你可能感兴趣的文章
Spring MVC整合Velocity
查看>>
fiddler+android抓包工具配置使用
查看>>
Spring Data JPA 复杂/多条件组合分页查询
查看>>
css文本 颜色1
查看>>
博客搬家了
查看>>
JavaScript中的作用域,闭包和上下文
查看>>
Python中使用ElementTree解析xml
查看>>
Python LOGGING使用方法
查看>>
Dominating Patterns
查看>>
截取指定字符串
查看>>
metrics-server最新版本有坑,慎用
查看>>
linux虚拟文件系统浅析
查看>>
HBase数据压缩编码探索
查看>>
sprint计划会议总结
查看>>
团队项目冲刺1
查看>>
fon循环总是返回最后值问题
查看>>
Android新权限机制 AppOps
查看>>
“蓝桥杯”软件大赛入门训练4道题
查看>>
[2010山东ACM省赛] Greatest Number(数的组合+二分搜索)
查看>>
Unable to get the CMake version located at
查看>>