备忘录模式(Memento Design Pattern)

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

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

目的

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

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

也称为

令牌(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模式时

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

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

查看所有标签

猜你喜欢:

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

奔跑吧,程序员

奔跑吧,程序员

[美]叶夫根尼·布里克曼(Yevgeniy Brikman) / 吴晓嘉 / 人民邮电出版社 / 2018-7 / 99.00元

本书以软件工程师出身的创业者的角度,全面介绍了创业公司该如何打造产品、实现技术和建立团队,既是为创业者打造的一份实用入门指南,又适合所有程序员系统认识IT行业。书中内容分为三部分——技术、产品和团队,详细描绘创业的原始景象,具体内容包括:创业点子、产品设计、数据与营销、技术栈的选择、整洁的代码、软件交付、创业文化、招兵买马,等等。一起来看看 《奔跑吧,程序员》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

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

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具