Design PatternsBehavioral

Memento

Capture and externalize an object's internal state so it can be restored later, without violating encapsulation.

3 min readDesigns · LLD & Patterns

Intent

Save a snapshot of an object's state to an opaque token (the memento) and use it later to restore that state — without exposing the internals.

Use when:

  • You need undo/redo.
  • You need to checkpoint state for rollback (transactions, save games).
  • You want to externalize state without breaking encapsulation.

Three Roles

RoleResponsibility
OriginatorThe object whose state needs saving. Creates and restores from mementos.
MementoAn opaque token holding a snapshot. Only originator can read it.
CaretakerHolds mementos. Doesn't peek inside them. Knows when to save/restore.

Structure

StructureClass diagram

Example: Editor with Undo

public class Editor {
    private String content = "";

    public void type(String text) { content += text; }
    public String getContent() { return content; }

    // Originator creates a memento
    public Memento save() { return new Memento(content); }

    // Originator restores from a memento
    public void restore(Memento m) { this.content = m.state; }

    // Memento — internal class so only Editor can construct & read it
    public static final class Memento {
        private final String state;
        private Memento(String state) { this.state = state; }
    }
}

public class History {
    private final Deque<Editor.Memento> stack = new ArrayDeque<>();

    public void save(Editor editor) { stack.push(editor.save()); }

    public void undo(Editor editor) {
        if (!stack.isEmpty()) editor.restore(stack.pop());
    }
}

Usage

Editor editor = new Editor();
History history = new History();

editor.type("Hello ");
history.save(editor);

editor.type("World");
history.save(editor);

editor.type("!");
System.out.println(editor.getContent());   // Hello World!

history.undo(editor);
System.out.println(editor.getContent());   // Hello World

history.undo(editor);
System.out.println(editor.getContent());   // Hello 

The History (caretaker) holds mementos but cannot inspect or modify them. The Memento is opaque to anyone but the Editor.


Why Encapsulation Matters

A naive approach exposes a public getState() / setState() on the originator. Then any caller can muck with internal state:

// Bad — leaks internals
String state = editor.getInternalState();   // public
externalSystem.tamper(state);
editor.setInternalState(tamperedState);

With memento, the snapshot is sealed:

Editor.Memento m = editor.save();
// no public methods on Memento — caller can hold it but not modify
editor.restore(m);

Memento vs Command Undo

Both support undo, with different trade-offs:

PatternStoresProCon
MementoFull snapshot of stateTrivial restore (just copy)Memory: every snapshot is full state
Command undoInverse operationMemory: only the diffComplex undo logic per command

For small state, memento wins on simplicity. For large state with small changes, command undo wins on memory.

Hybrid: memento for occasional checkpoints + command for fine-grained between checkpoints.


Memory Optimization

Incremental mementos

Instead of full state, store the diff from the previous memento:

class IncrementalMemento {
    final int position;
    final char insertedOrDeletedChar;
    // reconstruct by replaying
}

Limit history depth

class History {
    private final Deque<Memento> stack = new ArrayDeque<>();
    private final int maxSize = 50;

    public void save(Memento m) {
        stack.push(m);
        while (stack.size() > maxSize) stack.removeLast();
    }
}

Real-world Examples

Use caseMemento
Text editor undoDocument state snapshot
Game save pointsPlayer state at checkpoint
Database transactionsPre-commit snapshot for rollback
Form draftsAuto-saved form state
Caretaker in OS process snapshotsProcess state for fault tolerance
Browser back buttonPrevious page state

Combining with Command

Often used together:

class TypeCommand implements Command {
    private final Editor editor;
    private final String text;
    private Editor.Memento before;

    public void execute() {
        before = editor.save();
        editor.type(text);
    }

    public void undo() { editor.restore(before); }
}

Each command stores a memento for its own undo.


Trade-offs

✅ Pros:

  • Preserves encapsulation
  • Simple restore — just copy state back
  • Caretaker is decoupled from internal state

❌ Cons:

  • Memory: each snapshot is a full copy (mitigate with diffs / limits)
  • Caretaker controls lifetime — bug there leaks memory
  • Deep cloning of complex state is tricky (same as prototype)

Interview Tips

  • Reach for memento when the interviewer asks for undo, save points, or rollback.
  • Make the memento's fields private and use a nested class so only the originator can build/read it.
  • Compare to command undo — show you understand the memory vs simplicity tradeoff.

Finished reading?

Mark it done to track your progress in Designs.