Das Memento‑Pattern erfasst den Zustand eines Objekts, sodass er später wiederhergestellt werden kann, ohne die interne Darstellung preiszugeben.
Die drei Rollen
- Originator: erzeugt Snapshots und kann sie wiederherstellen.
- Memento: bewahrt einen unveränderlichen Snapshot.
- Caretaker: verwaltet Snapshots, ohne sie zu interpretieren.
class TextEditor {
private content = '';
type(text: string) { this.content += text; }
save(): EditorMemento { return new EditorMemento(this.content); }
restore(snapshot: EditorMemento) { this.content = snapshot.state(); }
}
class EditorMemento {
constructor(private readonly value: string) {}
state() { return this.value; }
}
Die Sichtbarkeitsregeln können je nach Sprache strenger umgesetzt werden. Entscheidend ist, dass der Caretaker den Snapshot nicht verändert, weil eine solche Veränderung die internen Invarianten des Originators verletzen und damit die Kapselung zerstören könnte.
Undo und Redo
Zwei Stapel können Snapshots vor und nach Änderungen aufnehmen:
class History {
private undoStack: EditorMemento[] = [];
private redoStack: EditorMemento[] = [];
undo(editor: TextEditor) {
const previous = this.undoStack.pop();
if (!previous) return false;
this.redoStack.push(editor.save());
editor.restore(previous);
return true;
}
}
Diese Mechanik ermöglicht es Nutzern, problemlos zu früheren Zuständen zurückzukehren, was besonders für Texteditoren und andere Anwendungen von Nutzen ist, in denen häufig Rollbacks und Redos erforderlich sind. Eine vollständige Implementierung muss zudem festlegen, wann Snapshots erstellt werden und wann der Redo‑Stapel geleert wird, um die Historie effizient und handhabbar zu halten.
Wo es passt
Memento eignet sich für Texteditoren, Grafikwerkzeuge, Konfigurations‑Rollbacks, Spielstände und Workflow‑Checkpoints. Durch die Wiederherstellung früherer Zustände ohne Datenverlust oder -korruption bietet es eine sichere Methode, um die Arbeit fortzusetzen.
Es ist jedoch weniger geeignet für sehr große Zustände, häufige Snapshots oder Zustände, die über mehrere Prozesse verteilt sind. Denn jede Aufnahme des kompletten Zustands verbraucht proportional Speicher und kann die Leistungsfähigkeit beeinträchtigen. In solchen Fällen können Delta‑Speicherung oder befehlsgesteuertes Undo effektiver sein.
Für große oder verteilte Systeme können Alternativen wie Delta‑Speicherung, Event‑Sourcing oder befehlsgesteuertes Undo eingesetzt werden. Jede dieser Optionen bringt eigene Komplexität mit sich, und die Wahl der richtigen Strategie hängt von den spezifischen Anforderungen und Einschränkungen des Systems ab.
Memento und Command
| Muster | Speichert | Undo‑Ansatz |
|---|---|---|
| Memento | Zustands‑Snapshot | Vorherigen Zustand wiederherstellen |
| Command | Aktion und Parameter | Ausgleichende Aktion ausführen |
Memento speichert einen vollständigen Zustands‑Snapshot und reaktiviert diesen, wenn eine Undo‑Operation angefordert wird. Im Gegensatz dazu dokumentiert das Command‑Muster Aktionen und Parameter und führt eine Ausgleichsaktion aus, um Änderungen rückgängig zu machen. Welches Muster sinnvoll ist, hängt davon ab, ob der gesamte Zustand oder lediglich die auszuführenden Aktionen gesichert werden müssen.
Beide Muster haben ihre Stärken und werden gemäß den spezifischen Bedürfnissen der Anwendung gewählt. Memento ist ideal für Situationen, in denen der gesamte Zustand gespeichert werden muss, während Command besser für Szenarien geeignet ist, in denen Änderungen durch Ausgleichsoperationen rückgängig gemacht werden können.
Fazit
Memento schützt die Kapselung und ermöglicht Rollbacks. Der Preis dafür ist Speicher: Jeder Snapshot belegt RAM oder persistenten Speicher. Deshalb muss man die Historie begrenzen und die Größe des Zustands messen, bevor man das Memento‑Pattern anwendet, um einen unnötigen Ressourcenverbrauch zu vermeiden.

Comments (0)
Please sign in to leave a comment