Back to All Design Patterns
Pattern 20 of 22
Behavioral PatternINTERMEDIATE7 min deep dive
Memento Pattern Pattern
Lets you save and restore the previous state of an object without revealing the details of its implementation.
Real-World Mental Model / Metaphor:
A game save checkpoint or git commit. You take a snapshot of the current state and stash it. If you die or make a mistake, you can reload the exact snapshot without exposing private variables.
Interactive Runtime Simulator
Test and tweak inputs dynamicallyInteractive Memento Pattern SimulatorLIVE PLAYGROUND
Interact with the controls below to see how this design pattern executes in memory at runtime.
Configure Chain Handlers (Toggle Failures):
CHAIN PIPELINE STATUS
Step 1: AuthHandler.check() -> PASSED
Step 2: RateLimitHandler.check() -> PASSED
Step 3: PayloadGuard.check() -> PASSED
The Problem It Solves
Allowing an external History or Caretaker manager to save snapshots of an object without making its private fields public.
The Architectural Solution
The Originator produces a Memento (an opaque snapshot). The Caretaker stores mementos in a stack and passes them back to the Originator to restore state.
Pattern Structure & Participants
| Participant | Role & Responsibility | Type |
|---|---|---|
| Originator (Editor) | Creates mementos and restores state from them | class |
| Memento (Snapshot) | Immutable state container | class |
| Caretaker (History Stack) | Stores list of mementos without inspecting contents | class |
Collaboration Rules:
- Originator.save() -> returns new Memento(state)
- Caretaker pushes to stack; on undo: Originator.restore(memento)
Production Code Implementation
Memento Pattern.java
// Memento (Immutable Snapshot)
public record EditorMemento(String text, int cursorPosition) {}
// Originator
public class TextEditor {
private String text = "";
private int cursor = 0;
public void write(String words) {
text += words;
cursor = text.length();
}
public EditorMemento save() {
return new EditorMemento(text, cursor);
}
public void restore(EditorMemento memento) {
this.text = memento.text();
this.cursor = memento.cursorPosition();
}
}
// Caretaker
public class HistoryManager {
private final Deque<EditorMemento> history = new ArrayDeque<>();
public void push(EditorMemento memento) { history.push(memento); }
public EditorMemento pop() { return history.pop(); }
} When to Use:
- •When you want to produce snapshots of the object's state to be able to restore a previous state.
- •When direct access to the object's fields/getters/setters violates its encapsulation.
When to Avoid (Anti-Pattern):
- •When snapshots consume vast amounts of memory (frequent snapshots of gigabyte datasets cause OOM).
Staff Engineering Interview Insights & Gotchas
- Explain how Memento pairs with the Command pattern to implement Undo/Redo stacks.