design·lab

Behavioral pattern

Memento

Save and restore an object's state — like an editor's undo — without ever exposing what's inside it.

✗ The problem

Undo needs state you're not supposed to touch

You want to snapshot an object and restore it later. But its fields are private — so either you leak them out, or undo simply can't happen.

class Editor {
  #text = "";

  // ✗ exposing the raw buffer just so SOMETHING
  // else can save/restore it later
  getInternalBuffer() { return this.#text; }
  setInternalBuffer(t) { this.#text = t; }
}
Leaking internal state just to support undo is a design smell — now every caller can read and mutate the editor's guts.
✓ The pattern

Three roles: Originator, Memento, Caretaker

The Originator makes an opaque Memento of itself and restores from one. The Caretaker stores mementos — but never looks inside.

class Editor {              // Originator
  save()    { return { text: this.text }; }   // Memento
  restore(m){ this.text = m.text; }
}
Originator
Editor
Memento
{ text }
Caretaker
history stack
✓ See it live

Edit, snapshot, undo

Type in the editor, click Snapshot to push a memento onto the history stack, keep editing, then Undo to restore the last saved state.

Originator — editor

Caretaker — history stack

0 snapshots saved

The caretaker only ever holds { text } objects — it never reads or edits them.

✓ Takeaway

Snapshot state without breaking encapsulation

  • Capture and restore state while the object's internals stay private.
  • Powers: undo/redo, checkpoints, transactions, save-games.
  • Pairs naturally with Command for undoable actions.
  • Careful: many or large snapshots cost memory — trim the history stack.
🎯 Principle applied: Memento preserves encapsulation (state stays private) and gives state-keeping its own role (SRP) — the caretaker never peeks inside.