内容简介:在不违反封装的情况下,捕获对象的内部状态并将其外部化,以便稍后将该对象还原到此状态。现实中最好的例子之一是文本编辑器,我们可以随时保存它的数据,并使用“撤消”将其恢复到以前保存的状态。
目的
在不违反封装的情况下,捕获对象的内部状态并将其外部化,以便稍后将该对象还原到此状态。
现实中最好的例子之一是文本编辑器,我们可以随时保存它的数据,并使用“撤消”将其恢复到以前保存的状态。
也称为
令牌(taken)
结构
参与者
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模式时
- 必须保存对象状态的快照,以便以后可以将其恢复到该状态
- 获取状态的直接接口将暴露实现细节并破坏对象的封装
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。