备忘录模式(Memento Design Pattern)

栏目: 后端 · 发布时间: 6年前

内容简介:在不违反封装的情况下,捕获对象的内部状态并将其外部化,以便稍后将该对象还原到此状态。现实中最好的例子之一是文本编辑器,我们可以随时保存它的数据,并使用“撤消”将其恢复到以前保存的状态。

目的

在不违反封装的情况下,捕获对象的内部状态并将其外部化,以便稍后将该对象还原到此状态。

现实中最好的例子之一是文本编辑器,我们可以随时保存它的数据,并使用“撤消”将其恢复到以前保存的状态。

也称为

令牌(taken)

结构

备忘录模式(Memento Design Pattern)

参与者

1.Memento

  • 该组件存储Originator对象的内部状态。纪念品可以根据发起人的判断,尽可能多地存储发起人的内部状态。
  • 此组件可防止发件人以外的对象访问。Mementos有效地有两个接口。看守人看到了Memento的狭窄界面 - 它只能将纪念品传递给其他物品。相比之下,Originator看到了一个宽广的界面,可以让它访问将自身恢复到之前状态所需的所有数据。理想情况下,只允许制作纪念品的发起人进入纪念品的内部状态。

2.Originator(创建者)

  • 该组件创建一个包含其当前内部状态快照的Memento 。
  • 该组件使用memento来恢复其内部状态。

3.Caretaker(看守者)

  • 它负责纪念品的保管。
  • 它从未对纪念品的内容进行操作或检查

源代码

备忘录模式是通过两个对象实现的——创建者(Originator)和看守者(Caretaker)。

Originator 是需要保存和恢复其状态的对象,它使用一个内部类来保存对象的状态。内部类称为memento,它是私有的,因此不能从其他对象访问它。

Caretaker 是帮助类,负责通过Memento对象存储和恢复Originator的状态。由于Memento对Originator是私有的,因此Caretaker无法访问它,它作为对象存储在Caretaker中。

第1步:让我们创建 Originator Class。

<b>public</b> <b>class</b> FileWriterUtil {
 <b>private</b> String fileName;
 <b>private</b> StringBuilder content;
 <b>public</b> FileWriterUtil(String file) {
  <b>this</b>.fileName = file;
  <b>this</b>.content = <b>new</b> StringBuilder();
 }

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

注意 Memento 内部类以及save和undo方法的实现。现在我们可以继续实现Caretaker类。

第2步:创建Caretaker类

<b>public</b> <b>class</b> FileWriterCaretaker {
 <b>private</b> Object obj;

 <b>public</b> <b>void</b> save(FileWriterUtil fileWriter) {
  <b>this</b>.obj = fileWriter.save();
 }
 
 <b>public</b> <b>void</b> undo(FileWriterUtil fileWriter) {
  fileWriter.undoToLastSave(obj);
 }
 
}

注意, caretaker对象是以对象的形式包含保存的状态,因此它不能更改其数据,也不了解其结构。

第3步:让我们测试memento模式。编写一个简单的测试程序,它将使用我们的memento实现。

<b>public</b> <b>class</b> FileWriterClient {
 <b>public</b> <b>static</b> <b>void</b> main(String args) {
  FileWriterCaretaker caretaker = <b>new</b> FileWriterCaretaker();
  FileWriterUtil fileWriter = <b>new</b> FileWriterUtil(<font>"data.txt"</font><font>);
  fileWriter.write(</font><font>"First Set of Data\n"</font><font>);
  System.out.println(fileWriter + </font><font>"\n\n"</font><font>);
  </font><font><i>// lets save the file</i></font><font>
  caretaker.save(fileWriter);
  </font><font><i>//now write something else</i></font><font>
  fileWriter.write(</font><font>"Second Set of Data\n"</font><font>);
  </font><font><i>//checking file contents</i></font><font>
  System.out.println(fileWriter + </font><font>"\n\n"</font><font>);
  </font><font><i>//lets undo to last save</i></font><font>
  caretaker.undo(fileWriter);
 }
</font>

适用性

使用Memento模式时

  • 必须保存对象状态的快照,以便以后可以将其恢复到该状态
  • 获取状态的直接接口将暴露实现细节并破坏对象的封装

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你不知道的JavaScript(上卷)

你不知道的JavaScript(上卷)

[美] Kyle Simpson / 赵望野、梁杰 / 人民邮电出版社 / 2015-4 / 49.00元

JavaScript语言有很多复杂的概念,但却用简单的方式体现出来(比如回调函数),因此,JavaScript开发者无需理解语言内部的原理,就能编写出功能全面的程序;就像收音机一样,你无需理解里面的管子和线圈都是做什么用的,只要会操作收音机上的按键,就可以收听你喜欢的节目。然而,JavaScript的这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发者,如果没有认真学习也无......一起来看看 《你不知道的JavaScript(上卷)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具