备忘录模式

备忘录模式是一种软件设计模式，可以将一个物件内部私有的状态公开。可以使用此模式的一个例子是将物件回复到其先前的状态（撤消变更），还有的例子是版本控制，以及自定义序列化。
备忘录模式主要由三个角色来实现：发起者、看守员和备忘录。发起者是具有内部状态的角色。看守员可以对发起者做一些操作，尤其是希望能够撤消变更的操作。看守员首先向发起者索要一件备忘录。然后它执行此操作（或操作序列）。若要回滚到操作之前的状态，它可以将备忘录返回给发起者。备忘录本身是一个的物件（看守员不能或不应更改此物件）。使用此模式时，应注意发起者是否可能更改其他物件或资源——备忘录模式是对单一物件进行操作。
备忘录模式的经典范例有伪随机数生成器（PRNG）（每个消费者（看守员）在初始化伪随机数生成器（发起者）时，若使用相同的种子值（备忘录），可以产生相同的乱数序列），此外，还有有限状态机及其状态。
概述.
备忘录设计模式是著名的《设计模式：可复用物件导向软体的基础》所收录的二十三个之一。此书描述了如何解决常见的设计问题，以设计出弹性且异重用的物件导向软件（亦即更容易实现、更改、测试、维护和重用的物件）。备忘录模式是由Noah Thompson、David Espiritu和Drew Clinkenbeard博士为惠普早期产品创建的。
备忘录设计模式可以解决什么问题？
问题在于，一个良好设计的物件会被封装起来，其表示（资料结构）是隐藏在物件内部，且无法从外部存取。
备忘录设计模式描述了什么解决方案？
这使得外部能够在不破坏其封装的情况下，保存和回复发起者的内部状态。请参考下面的 UML 类别图和序列图。
结构.
UML 类别图和序列图.
在上面的UML类图中， codice_1 类别指向了 codice_2 类别，用于保存（ codice_3 ）和恢复（ codice_4 ）始发者的内部状态。codice_2 类别实现了(1) codice_3 ，借由创建并返回 codice_7 物件，其记录了发起者当前内部状态，(2) codice_4，借由将 codice_7 物件传入，以回复状态。
UML序列图显示了运行时交动：(1) 保存发起者的内部状态： codice_1对象在codice_2对象上调用codice_3 ，创建一个codice_7对象，保存其当前的内部状态 ( codice_14 )，并将codice_7返回给codice_1 。(2) 恢复Originator的内部状态： codice_1对codice_2对象调用codice_4 ，并指定存储应恢复状态的codice_7对象。 codice_2从codice_7获取状态 ( codice_23 ) 以设置自己的状态。
范例.
Java.
以下的Java程序说明了备忘录模式的“撤消变更”用法。
import java.util.List;
import java.util.ArrayList;
class Originator {
 private String state;
 // 这个类别可以包含其它不用存在 State 中的备忘录
 public void set(String state) {
 this.state = state;
 System.out.println("Originator: Setting state to " + state);
 
 public Memento saveToMemento() {
 System.out.println("Originator: Saving to Memento.");
 return new Memento(this.state);
 
 public void restoreFromMemento(Memento memento) {
 this.state = memento.getSavedState();
 System.out.println("Originator: State after restoring from Memento: " + state);
 
 public static class Memento {
 private final String state;
 public Memento(String stateToSave) {
 state = stateToSave;
 
 // accessible by outer class only
 private String getSavedState() {
 return state;
 
class Caretaker {
 public static void main(String[] args) {
 List&lt;Originator.Memento&gt; savedStates = new ArrayList&lt;Originator.Memento&gt;();
 Originator originator = new Originator();
 originator.set("State1");
 originator.set("State2");
 savedStates.add(originator.saveToMemento());
 originator.set("State3");
 // 我们可以要求多个备忘录，并选择要回复到那个状态。
 savedStates.add(originator.saveToMemento());
 originator.set("State4");
 originator.restoreFromMemento(savedStates.get(1)); 
输出是：
 Originator: Setting state to State1
 Originator: Setting state to State2
 Originator: Saving to Memento.
 Originator: Setting state to State3
 Originator: Saving to Memento.
 Originator: Setting state to State4
 Originator: State after restoring from Memento: State3
本示例使用 String 作为状态，它是 Java 中的不可变物件。在现实生活中，状态几乎总是一个可变物件，在这种情况下，必须创建状态的副本。
必须指出的是，所展示的实现有一个缺点：它声明了一个内部类。如果备忘录可以适用于多个发起者，则会更好。
实现Memento 还有其他三种主要方式：
C#.
备忘录模式允许人们在不违反封装的情况下捕获物件的内部状态，以便以后可以根据需求来撤消变更/回复变更。从这里可以看出，备忘录物件实际上用于恢复物件中所做的更改。
class Memento {
 private readonly string savedState;
 private Memento(string stateToSave) {
 savedState = stateToSave;
 public class Originator {
 private string state;
 // The class could also contain additional data that is not part of the
 // state saved in the memento.
 public void Set(string state) {
 Console.WriteLine("Originator: Setting state to " + state);
 this.state = state;
 public Memento SaveToMemento() {
 Console.WriteLine("Originator: Saving to Memento.");
 return new Memento(state);
 public void RestoreFromMemento(Memento memento) {
 state = memento.savedState;
 Console.WriteLine("Originator: State after restoring from Memento: " + state);
class Caretaker {
 static void Main(string[] args) {
 var savedStates = new List&lt;Memento&gt;();
 var originator = new Memento.Originator();
 originator.Set("State1");
 originator.Set("State2");
 savedStates.Add(originator.SaveToMemento());
 originator.Set("State3");
 // We can request multiple mementos, and choose which one to roll back to.
 savedStates.Add(originator.SaveToMemento());
 originator.Set("State4");
 originator.RestoreFromMemento(savedStates[1]);
Python.
下面是Python例子：
class Originator():
 __state = None
 def set(self, state):
 print(f"Originator: Setting state to {state}")
 self.__state = state
 def save_to_memento(self):
 return self.__Memento(self.__state)
 def restore_from_memento(self, mem):
 self.__state = mem.get_saved_state()
 print(f"Originator: State after restoring from Memento: {self.__state}")
 class __Memento():
 def __init__(self, state):
 self.__state = state
 def get_saved_state(self):
 return self.__state
def caretaker():
 saved_states = []
 originator = Originator()
 originator.set("State1")
 originator.set("State2")
 saved_states += [originator.save_to_memento()]
 originator.set("State3")
 saved_states += [originator.save_to_memento()]
 originator.set("State4")
 originator.restore_from_memento(saved_states[1])
其执行：
»&gt; caretaker()
Originator: Setting state to State1
Originator: Setting state to State2
Originator: Setting state to State3
Originator: Setting state to State4
Originator: State after restoring from Memento: State3
JavaScript.
// The Memento pattern is used to save and restore the state of an object.
// A memento is a snapshot of an object's state.
var Memento = {// Namespace: Memento
 savedState : null, // The saved state of the object.
 save : function(state) { // Save the state of an object.
 this.savedState = state;
 restore : function() { // Restore the state of an object.
 return this.savedState;
};
// The Originator is the object that creates the memento.
// defines a method for saving the state inside a memento.
var Originator = {// Namespace: Originator
 state : null, // The state to be stored
 // Creates a new originator with an initial state of null
 createMemento : function() { 
 return {
 state : this.state // The state is copied to the memento.
 },
 setMemento : function(memento) { // Sets the state of the originator from a memento
 this.state = memento.state;
};
// The Caretaker stores mementos of the objects and
// provides operations to retrieve them.
var Caretaker = {// Namespace: Caretaker
 mementos : [], // The mementos of the objects.
 addMemento : function(memento) { // Add a memento to the collection.
 this.mementos.push(memento);
 getMemento : function(index) { // Get a memento from the collection.
 return this.mementos[index];
};
var action_step = "Foo"; // The action to be executed/the object state to be stored.
var action_step_2 = "Bar"; // The action to be executed/the object state to be stored.
// 设置初始值
Originator.state = action_step;
Caretaker.addMemento(Originator.createMemento());// save the state to the history
console.log("Initial State: " + Originator.state); // Foo
// 改变初始值
Originator.state = action_step_2;
Caretaker.addMemento(Originator.createMemento()); // save the state to the history
console.log("State After Change: " + Originator.state); // Bar
// 回复到第一个状态——撤消变更
Originator.setMemento(Caretaker.getMemento(0));
console.log("State After Undo: " + Originator.state); // Foo
// 回复到第二个状态——重做变更
Originator.setMemento(Caretaker.getMemento(1));
console.log("State After Redo: " + Originator.state); // Bar