Memento

From CDOT Wiki
Revision as of 17:29, 13 April 2007 by Ajhooper (talk | contribs)
Jump to: navigation, search


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 makes sure that only the object that creates the memento will be able to access it to restore it's state. Although if can have other uses, this pattern is often used for undo/redo operations in many different programs.

Diagram

MementoDiagram.jpg

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
*/


References

Data & Object Factory Wikipedia