skip to content

Memento in Java

Memento snapshots an object's internal state into an opaque token so it can be restored later, typically for undo, without exposing the internals. In Java the discussion turns on how you capture the snapshot and what it costs in memory.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is the Memento design pattern, and what are its three roles in Java?

level: juniorimportance: should knowfreq 45%

answer

  1. Three roles: Originator / Memento / Caretaker
  2. Snapshot + restore without breaking encapsulation
  3. Caretaker treats memento as a black box
  4. Classic use: undo (stack of mementos)
  5. Originator creates and reads; nobody else reads

basics

~20 s

Memento lets you save an object's state to a separate object and restore it later (e.g. undo), without exposing the object's internals. The three roles are Originator (owns the state), Memento (the saved snapshot), and Caretaker (holds mementos but never reads them).

solid answer

~50 s

Memento is a behavioral GoF pattern that captures an object's internal state in a snapshot object so the object can later be restored to that state, without violating encapsulation. It has three roles. The Originator is the object whose state we save; it creates a Memento (save()) and can restore itself from one (restore(m)). The Memento is an opaque snapshot holding a copy of the relevant state; ideally only the Originator can read its contents. The Caretaker requests and stores mementos (often in a stack for undo/redo) but treats each as a black box and never inspects or mutates it. The classic Java use is undo: before each change the Caretaker asks the Originator for a memento; to undo, it hands the previous memento back. The key benefit is that state is externalized for rollback while the Originator's fields stay private.

go deeper

for a junior

Can name the pattern's purpose (save/restore state for undo) and recall the three roles. Recognizes that the memento is a separate snapshot object.

for a middle

Explains why the Caretaker must not read the memento (encapsulation) and can sketch an undo stack. Distinguishes Memento from Command.

for a senior

Implements the narrow/wide interface correctly in Java (private nested class or record), handles deep vs shallow copy, and reasons about memory cost and history bounding.

for a principal

Weighs full-snapshot vs delta/Command-based undo for large state, considers serialization cost and persistence of mementos, and sets policy on history depth and memory budgets across a system.

## The problem Memento solves Suppose you have an object that changes over time — a text editor's document, a game character, a drawing canvas — and you want an **undo** feature. To undo, you must be able to restore a *previous* state of that object. The naive approach is to let some external 'history manager' reach into the object, read all its fields, stash them, and later write them back. But that **breaks encapsulation**: the history manager now depends on the object's private structure, and the object can't change its internals freely. **Memento** (a behavioral pattern from the Gang of Four catalog) solves this: the object itself produces a snapshot of its own state as a separate object, and can later rebuild itself from such a snapshot — all without exposing its fields to the outside world. ## Definitions of the three roles - **Originator** — the object whose state we want to save and restore. It has two key operations: one that **creates** a memento capturing its current state (often called `save()` or `createMemento()`), and one that **restores** its state from a given memento (`restore(memento)`). Only the Originator knows what is inside a memento and how to interpret it. - **Memento** — the **snapshot object**. It is an immutable (ideally) value holder containing a *copy* of whatever state the Originator needs to reconstruct itself. Critically, the Memento is **opaque to everyone except the Originator**: outsiders may hold a reference to it and pass it around, but they cannot read or change its contents. - **Caretaker** — the code that *manages* mementos: it asks the Originator to produce one, stores it (commonly on a stack so the most recent state is restored first, enabling undo; a second stack gives redo), and later hands one back to the Originator to restore. The Caretaker treats each memento as a **black box** — it never looks inside. ## How encapsulation is preserved in Java The trick is a **narrow vs. wide interface**. The Caretaker sees only a *narrow* interface (often just a marker/empty type), while the Originator sees the *wide* interface (the actual fields). Java idioms to achieve this: 1. **Memento as a `private static` nested class of the Originator.** The Originator can access the nested class's private fields (Java lets an enclosing class see a nested class's privates and vice versa), but outside code only gets a reference typed as a public marker interface, so it can't read anything. 2. **`record` for the Memento.** A Java `record` makes a compact, immutable snapshot with value-based `equals`/`hashCode` — a natural fit for an opaque state holder. ## Two common Java ways to capture state - **Private field snapshot:** the Originator copies its current field values into the Memento. This is fast and explicit but must be kept in sync with the Originator's fields. Watch for **shallow vs deep copy** — if a field is a mutable object (e.g. a `List`), copying only the reference means a later mutation corrupts the saved snapshot, so you must defensively copy mutable state. - **Serialization-based memento:** serialize the whole Originator (e.g. `Serializable` + `ObjectOutputStream`, or a deep clone) into a byte array, and deserialize to restore. This automatically produces a **deep copy** and needs no manual field-by-field code, but it is slower, requires `Serializable`, and stores a lot of bytes. ## Memory cost Every saved state is a full (often deep) copy of the relevant data. An unbounded undo history therefore grows memory linearly with the number of saved states. Mitigations: **cap the history depth**, store **deltas** (only what changed) instead of full snapshots, or snapshot lazily. ## Contrast with related ideas - **Command pattern** also enables undo, but by storing the *operations* (and their inverses) rather than full state snapshots; the two are often combined (Command holds a Memento to undo). - **Prototype/clone** copies an object for general reuse; Memento copies specifically for later **restoration of the same object**, with the encapsulation guarantee. In the JDK itself there is no single canonical Memento class, but the idea shows up wherever state is snapshotted for rollback (e.g. transactional or 'savepoint' style APIs).

  • Why shouldn't the Caretaker be allowed to read the memento's contents?
    Because that would re-expose the Originator's internal representation to outside code, defeating the encapsulation the pattern exists to protect. The Caretaker only needs to store and hand back mementos, not interpret them.
  • How do you typically support both undo and redo with Memento?
    Use two stacks: an undo stack and a redo stack. Saving a state pushes onto undo; undo pops from undo, pushes current onto redo, and restores the popped memento; redo does the reverse.

saying these in an interview costs you the question

  • Saying the Caretaker reads or modifies the memento's contents (it must not)
  • Confusing Memento with Command (Command stores operations, Memento stores state)
  • Claiming Memento exposes the Originator's internals — its whole point is the opposite
  • Forgetting that there are exactly three roles

context

open as a page

How do you implement a Memento in Java so that only the Originator can access the snapshot's state while the Caretaker still cannot read it?

level: middleimportance: should knowfreq 40%

basics

~20 s

Make the Memento a private (or private static) nested class of the Originator and expose it to the outside only through a public marker interface. The Originator can read the nested class's private fields; the Caretaker holds it as the marker type and can't see anything.

open as a page

What are the trade-offs between a serialization-based memento and a private field-snapshot memento in Java?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

A field-snapshot copies chosen fields by hand: fast, small, but you must write and maintain the copy code. A serialization-based memento serializes the whole object to bytes: automatic deep copy and no per-field code, but slower, larger, and needs Serializable.

open as a page

For an undo feature, when would you choose Memento (snapshots) over a Command-based approach, and how can the two combine?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

Memento undoes by restoring a saved full state; Command undoes by storing each operation and applying its inverse. Use Memento when full snapshots are cheap and inverses are hard to compute; use Command when state is large but each change is small. They combine: a Command can store a Memento to undo itself.

open as a page

An undo feature built on full-state mementos is consuming too much memory in production. How do you diagnose and reduce the cost while keeping correctness?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

Each memento is a full copy of state, so an unbounded history grows memory linearly. Fix it by bounding history depth, storing deltas instead of full snapshots, sharing immutable sub-state structurally, or moving older snapshots off-heap/to disk — choosing based on how big state is and how it changes.

open as a page