Memento (design pattern)

from Wikipedia, the free encyclopedia

A Memento (English memento pattern , even token ) is in the software development a design pattern that the category of behavioral patterns (English behavioral patterns is one). The pattern is used to record and externalize the internal state of an object, ensuring that its encapsulation is not violated. In this way, the object can be reset to this state at a later point in time. It is one of the so-called GoF patterns .

use

The memento applies when

  • a snapshot of the (partial) state of an object must be cached
  • the aim is to prevent a direct interface for determining the status from disclosing implementation details

A typical use case is, for example, the implementation of breakpoints or undo mechanisms.

actors

The memento pattern has the actors originator and memento. The originator is an object with an internal state that can be changed. This state can be saved in the memento in order to be restored at a later point in time.

advantages

  • Data encapsulation can be maintained, which means that there is no direct visibility or access to attributes of an object
  • The pattern is an easy way to create a partial interface

example

The following Java program represents the undo mechanism (undo) in Java.

public class MementoDemo {

  public static void main(String[] args) {
    Originator originator = new Originator();

    originator.set("State1");
    originator.set("State2");
    Memento memento1 = originator.saveToMemento();
    originator.set("State3");
    // We can request multiple mementos, and choose which one to roll back to.
    Memento memento2 = originator.saveToMemento();
    originator.set("State4");

    originator.restoreFromMemento(memento2);
  }
}

public class Memento {
  /** State of the memento */
  private final String state;

  public Memento(final String stateToSave) {
    state = stateToSave;
  }

  public String getSavedState() {
    return state;
  }
}

public class Originator {

  /** Current state */
  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) {
    System.out.println("Originator: Setting state to " + state);
    this.state = state;
  }

  public Memento saveToMemento() {
    System.out.println("Originator: Saving to Memento.");
    return new Memento(state);
  }

  public void restoreFromMemento(Memento memento) {
    state = memento.getSavedState();
    System.out.println("Originator: State after restoring from Memento: " + state);
  }

}

The output reads:

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

In this example, a is used Stringas the state, which is unchangeable by default in Java. Usually the state is a normal object that you have to clone before using it in the memento:

private Memento(final State state)
{
    // Der Zustand muss zuerst geklont werden, bevor
    // das Memento zurückgegeben wird, oder aufeinanderfolgende
    // Aufrufe würden auf ein und dasselbe Objekt zugreifen.
    mementoState = state.clone();
}

The implementation given above has a disadvantage in that it declares an internal class. It would be better if the memento strategy could be applied to more than one object.

There are basically three other ways of realizing a memento:

  1. The serialization.
  2. Declare a class in the same package.
  3. To the object through a proxy access that performs backup and restore operation.

Web links

  • RFC 7089 - HTTP Framework for Time-Based Access to Resource States - Memento (Mementos for web archiving )

Individual evidence

  1. Erich Gamma , Richard Helm , Ralph Johnson , John Vlissides : Design pattern . 5th edition. Addison-Wesley , 1996, ISBN 3-8273-1862-9 , pp. 354 .