Memento
Contents
Description
The Memento design pattern is used to store the state of an object so that it can later be restored to that state. In the diagram below the Originator object is creates a Memento that will store it's internal state and can later retrieve that state. The Caretaker is the object that creates the memento to store the date in the Originator. Although if can have other uses, this pattern is often used for undo/redo operations in many different programs.
Diagram
Examples
This is a simple example of a memento in C#:
// Memento pattern -- Structural example using System; namespace DoFactory.GangOfFour.Memento.Structural { // MainApp test application class MainApp { static void Main() { Originator o = new Originator(); o.State = "On"; // Store internal state Caretaker c = new Caretaker(); c.Memento = o.CreateMemento(); // Continue changing originator o.State = "Off"; // Restore saved state o.SetMemento(c.Memento); // Wait for user Console.Read(); } } // "Originator" class Originator { private string state; // Property public string State { get{ return state; } set { state = value; Console.WriteLine("State = " + state); } } public Memento CreateMemento() { return (new Memento(state)); } public void SetMemento(Memento memento) { Console.WriteLine("Restoring state:"); State = memento.State; } } // "Memento" class Memento { private string state; // Constructor public Memento(string state) { this.state = state; } // Property public string State { get{ return state; } } } // "Caretaker" class Caretaker { private Memento memento; // Property public Memento Memento { set{ memento = value; } get{ return memento; } } } } //Output //State = On //State = Off //Restoring state: //State = On
This is a simple example of a memento in Java:
import java.util.*; class Originator { private String state; /* lots of memory consumptive private data that is not necessary to define the * state and should thus not be saved. Hence the small memento object. */ public void set(String state) { System.out.println("Originator: Setting state to "+state); this.state = state; } public Object saveToMemento() { System.out.println("Originator: Saving to Memento."); return new Memento(state); } public void restoreFromMemento(Object m) { if (m instanceof Memento) { Memento memento = (Memento)m; state = memento.getSavedState(); System.out.println("Originator: State after restoring from Memento: "+state); } } private static class Memento { private String state; public Memento(String stateToSave) { state = stateToSave; } public String getSavedState() { return state; } } } class Caretaker { private ArrayList savedStates = new ArrayList(); public void addMemento(Object m) { savedStates.add(m); } public Object getMemento(int index) { return savedStates.get(index); } } class MementoExample { public static void main(String[] args) { Caretaker caretaker = new Caretaker(); Originator originator = new Originator(); originator.set("State1"); originator.set("State2"); caretaker.addMemento( originator.saveToMemento() ); originator.set("State3"); caretaker.addMemento( originator.saveToMemento() ); originator.set("State4"); originator.restoreFromMemento( caretaker.getMemento(1) ); } } /*Output: * * 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 */