100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Software Design

Memento Pattern

A behavioral pattern that captures and externalizes an object's internal state so it can be restored later, without violating encapsulation.

Behavioral Patterns IIIntermediate8 min readJul 10, 2026
Analogies

Snapshotting State Without Breaking Encapsulation

Many applications need undo functionality — a text editor reverting your last paragraph, a game restoring a save point, a form resetting to a prior draft. The naive approach is to expose all of an object's internal fields through public getters and setters so external code can copy and later restore them, but that permanently weakens encapsulation for every part of the system, not just the undo feature. The Memento pattern solves this by having the Originator (the object whose state needs saving) create an opaque Memento object that captures a snapshot of its own internal state, using its own privileged access to its fields. The Memento is handed to a Caretaker, which stores it (often in a stack for multiple undo levels) but cannot read or modify its contents — only the Originator that created it knows how to interpret a Memento to restore state from it.

🏏

Cricket analogy: A team's video analyst saves a specific bowling action snapshot for a player using footage only the analyst's software can fully decode, while the captain (the caretaker) just knows which snapshot to hand back for review without understanding the raw biomechanical data inside it.

The Three Roles: Originator, Memento, Caretaker

The Originator exposes two methods relevant to Memento: createMemento(), which packages current internal state into a new Memento instance, and restore(memento), which reads a given Memento's state back into itself. The Memento class itself is typically designed with a narrow interface — often just enough for the Caretaker to store and retrieve it, such as a getDate() or getLabel() method for display purposes, while the actual state payload is kept private or accessible only to the Originator (achieved in languages like C++ via friend classes, or more commonly in practice via a nested/inner class, or simply by convention in dynamically typed languages). The Caretaker is typically a stack or list of mementos representing undo history; on undo, it pops the most recent memento and passes it to originator.restore(memento), and can optionally support redo by keeping popped mementos on a separate redo stack instead of discarding them.

🏏

Cricket analogy: A DRS system's ball-tracking snapshot (the memento) is created and read only by the Hawk-Eye engine (the originator) itself, while the broadcast graphics team (the caretaker) just stores and replays the visualization without decoding the raw trajectory data.

typescript
class EditorMemento {
  constructor(private readonly content: string, private readonly cursorPos: number) {}

  // Only accessible to TextEditor via package-private convention
  getContent(): string {
    return this.content;
  }
  getCursorPos(): number {
    return this.cursorPos;
  }
}

class TextEditor {
  private content = '';
  private cursorPos = 0;

  type(text: string): void {
    this.content += text;
    this.cursorPos = this.content.length;
  }

  createMemento(): EditorMemento {
    return new EditorMemento(this.content, this.cursorPos);
  }

  restore(memento: EditorMemento): void {
    this.content = memento.getContent();
    this.cursorPos = memento.getCursorPos();
  }
}

class UndoStack {
  private history: EditorMemento[] = [];

  save(editor: TextEditor): void {
    this.history.push(editor.createMemento());
  }

  undo(editor: TextEditor): void {
    const last = this.history.pop();
    if (last) {
      editor.restore(last);
    }
  }
}

Memento in Practice: Redux, Git, and Beyond

Redux-style state management libraries implement a variant of Memento implicitly: every dispatched action produces a brand-new immutable state tree rather than mutating the previous one, so undo middleware like redux-undo can simply keep an array of prior state snapshots and swap the current pointer backward, exactly analogous to a caretaker's stack of mementos. Git commits are a similarly structured, if heavier-weight, form of Memento: each commit is an immutable snapshot of the entire repository tree, and checking out an earlier commit restores that exact snapshot. A key practical concern in real Memento implementations is the memory cost of storing full snapshots for every change — mitigations include storing deltas (diffs) instead of full copies, or using structural sharing (as in persistent data structures) so unchanged parts of the state are referenced rather than duplicated across mementos.

🏏

Cricket analogy: Cricinfo's ball-by-ball commentary archive keeps an immutable record of every delivery's outcome, letting you jump back to any exact moment of a match, much like Git commits or Redux states preserve immutable snapshots you can revert to.

Redux DevTools' time-travel debugging is a live demonstration of Memento: every action creates a new state snapshot, and 'jumping' to a previous action in the DevTools UI is literally restoring an earlier memento.

Storing a full deep copy of an object's state for every single change can consume significant memory in long-running applications with frequent state changes — profile memory usage and consider delta-based storage or structural sharing before naively snapshotting large objects on every action.

  • Memento captures an object's internal state externally so it can be restored later, without exposing that state through public getters/setters.
  • Three roles: Originator (creates/restores state), Memento (opaque snapshot), Caretaker (stores mementos without reading them).
  • The Caretaker typically maintains a stack of mementos to support multi-level undo, and optionally a redo stack.
  • Redux-style immutable state updates and Git commits are real-world variants of the Memento pattern.
  • Only the Originator understands how to interpret and restore from its own Memento's contents.
  • Naive full-snapshot storage can be memory-expensive; deltas or structural sharing mitigate this.
  • Memento preserves encapsulation, unlike exposing all internal fields via public accessors just for undo support.

Practice what you learned

Was this page helpful?

Topics covered

#SoftwareDesign#DesignPatternsStudyNotes#SoftwareEngineering#MementoPattern#Memento#Pattern#Snapshotting#State#StudyNotes#SkillVeris