备忘录模式(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模式时

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

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

查看所有标签

猜你喜欢:

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

Sprint

Sprint

Jake Knapp、John Zeratsky、Braden Kowitz / Simon & Schuster / 2016-3-8 / GBP 14.60

媒体推荐 “Every business leader I know worries about the same thing: Are we moving fast enough? The genius of Jake Knapp’s Sprint is its step-by-step breakdown of what it takes to solve big problems an......一起来看看 《Sprint》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换