Memento (Entwurfsmuster)
Ein Memento (englisch memento pattern, auch Token) ist in der Softwareentwicklung ein Entwurfsmuster, das zur Kategorie der Verhaltensmuster (englisch behavioral patterns) gehört. Das Muster dient der 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
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.
Akteure
Das Memento-Muster hat die Akteure Originator und Memento. Der Originator ist ein Objekt mit einem internen Zustand, der verändert werden kann. Im Memento kann dieser Zustand abgespeichert werden, um zu einem späteren Zeitpunkt wiederhergestellt zu werden.
Vorteile
- 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
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:
- Die Serialisierung.
- Eine Klasse im selben Paket zu deklarieren.
- Auf das Objekt über einen Stellvertreter zugreifen, der die Sicherungs- und Wiederherstellungsoperation durchführt.
Weblinks
- H. Van de Sompel, M. Nelson, R. Sanderson: RFC – HTTP Framework for Time-Based Access to Resource States -- Memento. Dezember 2013 (Mementos für die Web-Archivierung, englisch).
Einzelnachweise
- ↑ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5. Auflage. Addison-Wesley, 1996, ISBN 3-8273-1862-9, S. 354.