Skip to content

Memento

Memento captures an object’s internal state into a separate token so the state can be restored later, all without revealing how that state is stored. It is the pattern behind undo.

A text editor needs an undo command. To restore a previous state, something has to remember what the document looked like before each edit. The obvious approach — let the undo machinery read and write the editor’s private fields directly — breaks encapsulation: now the history code depends on the editor’s internal layout, and any change to that layout ripples outward.

Memento keeps the snapshot opaque. The object whose state you want to save (the originator) produces a memento that captures its state. A caretaker holds onto mementos but treats them as sealed boxes; it can hand one back to the originator to restore, but it cannot peek inside. The originator stays in full control of what gets saved and how, so its internals remain private even though its history is recorded.

classDiagram
  class Editor {
    -content: string
    +type(text)
    +save() Memento
    +restore(m Memento)
  }
  class Memento {
    -state: string
    +getState() string
  }
  class History {
    -snapshots: List~Memento~
    +push(m Memento)
    +pop() Memento
  }
  Editor ..> Memento : creates
  History o-- Memento : stores
  Editor ..> History : uses
The originator creates mementos; the caretaker stores them without inspecting them
  • Editor (Originator) — the object whose state matters. It creates a memento capturing its current state and can restore itself from one.
  • Memento — the opaque snapshot. Only the originator understands its contents; everyone else treats it as a black box.
  • History (Caretaker) — keeps a stack of mementos and decides when to save and when to roll back, without reading the snapshots.

A tiny editor with undo. Each save pushes a snapshot onto a history stack; undo pops the last snapshot and restores it.

class Memento {
constructor(readonly state: string) {}
}
class Editor {
private content = '';
type(text: string): void {
this.content += text;
}
read(): string {
return this.content;
}
save(): Memento {
return new Memento(this.content);
}
restore(m: Memento): void {
this.content = m.state;
}
}
class History {
private snapshots: Memento[] = [];
push(m: Memento): void {
this.snapshots.push(m);
}
pop(): Memento | undefined {
return this.snapshots.pop();
}
}
const editor = new Editor();
const history = new History();
editor.type('hello ');
history.push(editor.save());
editor.type('world');
console.log(editor.read()); // hello world
const snapshot = history.pop();
if (snapshot) editor.restore(snapshot);
console.log(editor.read()); // hello
  • Pro: enables undo, rollback, and checkpoints without exposing the originator’s internal fields.
  • Pro: the originator keeps full control over what is saved, so encapsulation stays intact.
  • Con: storing many full snapshots can be expensive in memory; large states may need diffing or limits.
  • Con: the caretaker must manage the lifetime of mementos, and stale snapshots can pile up if never discarded.
  • Command and Memento are natural partners for undo: a command can keep a memento of the state it changed and restore it when reversed.
  • Iterator can use a memento to capture its position when traversal state must survive outside the iterator.
What does the Memento pattern protect while saving state?
What is the role of the caretaker?
Which pattern most commonly pairs with Memento to implement undo?