Memento (Entwurfsmuster)

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Ein Memento (englisch memento pattern, auch Token) ist in der Softwareentwicklung ein Entwurfsmuster und gehört zur Kategorie der Verhaltensmuster (englisch behavioral patterns). Das Muster dient zur Erfassung und Externalisierung des internen Zustands eines Objektes, wobei sichergestellt wird, dass dadurch seine Kapselung nicht verletzt wird. So kann das Objekt zu einem späteren Zeitpunkt wieder in diesen Zustand zurückversetzt werden.[1] Es ist eines der sogenannten GoF-Muster.

Verwendung[Bearbeiten]

Das Memento findet Anwendung, wenn

  • eine Momentaufnahme des (Teil-)Zustands eines Objektes zwischengespeichert werden muss
  • verhindert werden soll, dass eine direkte Schnittstelle zur Ermittlung des Zustands Implementierungsdetails offenlegt

Ein typischer Anwendungsfall ist beispielsweise die Implementierung von Haltepunkten oder Undo-Mechanismen.

Vorteile[Bearbeiten]

  • Datenkapselung kann aufrechterhalten werden, womit keine direkte Sichtbarkeit beziehungsweise Zugriffsmöglichkeit auf Attribute eines Objekts entsteht
  • Das Muster stellt eine einfache Möglichkeit dar, eine teilweise Schnittstelle zu schaffen

Beispiel[Bearbeiten]

Folgendes Javaprogramm stellt den Rückgängig-Mechanismus (undo) in Java dar.

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);
  }
 
}

Die Ausgabe lautet:

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 diesem Beispiel wird ein String als Zustand verwendet, der in Java standardmäßig unveränderbar ist. Üblicherweise ist der Zustand aber ein normales Objekt, das man klonen muss, bevor man es im Memento verwendet:

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();
}

Die oben angegebene Implementierung hat einen Nachteil, indem sie eine interne Klasse deklariert. Es wäre besser, wenn die Memento-Strategie auf mehr als ein Objekt anwendbar wäre.

Grundsätzlich gibt es drei andere Wege, ein Memento zu realisieren:

  1. Die Serialisierung.
  2. Eine Klasse im selben Paket zu deklarieren.
  3. Auf das Objekt über einen Stellvertreter zugreifen, der die Sicherungs- und Wiederherstellungsoperation durchführt.

Einzelnachweise[Bearbeiten]

  1.  Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5 Auflage. Addison-Wesley, 1996, ISBN 3-8273-1862-9, S. 354.

Weblinks[Bearbeiten]