Memento Pattern
Capture and externalize an object's internal state so it can be restored later — without violating encapsulation.
📌 Key IdeaOriginator creates Memento snapshots; Caretaker stores them (doesn't peek inside). Undo stacks in editors, game save slots, transactional checkpoints.
Visual
🧠 Snapshot without breaking encapsulation
Editor.originator.save() → Memento Caretaker.stack.push(memento) ... edit ... Caretaker.pop().restore(editor)
Caretaker holds opaque token; only originator interprets memento.
When to Use
- Undo/redo beyond simple command inverse — need full state snapshot.
- Checkpoints / rollback for long-running edits.
- You must not expose originator's private fields to caretaker.
When NOT to Use
- State is huge — memory pressure (consider incremental command undo instead).
- Immutable state — often simpler to rebuild from operations.
Anti-Pattern (What NOT to Do)
Caretaker pokes private editor fieldsBadjava
void undo(Editor ed) {
ed.text = stack.pop(); // breaks encapsulation
ed.cursor = stack.pop();
}Caretaker shouldn't know how to reconstruct internals.
The Right Way
Opaque memento from originatorGoodjava
final class Editor {
private String text;
Memento save() { return new Memento(text); }
void restore(Memento m) { this.text = m.text(); }
private record Memento(String text) {} // narrow visibility
}Caretaker stores
Memento references blindly; only Editor reads fields.Pros & Cons
👍 Pros
- Preserves encapsulation boundaries.
- Clean separation: originator vs caretaker responsibilities.
👎 Cons
- Memory cost if snapshots are large or frequent.
- Careful with deep vs shallow copy semantics.
Common Confusions Cleared Up
Memento vs Command for undo
Command undo often stores reverse operation. Memento stores state snapshot when reversal isn't trivial or history branches.
Interview Q&A
Likely Follow-up Questions
- Copy-on-write for large documents?
Quick Cheat Sheet
IntentSnapshot state; restore later.
RolesOriginator, Memento, Caretaker.
Pairs withCommand (undo stack).