Home/Learn/Low Level Design/Memento Pattern

Memento Pattern

Intermediate
Behavioral Patterns

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

Overview

The Memento pattern enables undo functionality without exposing an object's internals. Three participants: Originator (the object whose state is saved), Memento (the snapshot — an opaque state holder), and Caretaker (manages the history of Mementos without inspecting them). The Originator creates and restores from Mementos; the Caretaker stores them. Java serialization can implement Memento for complex objects. The key design constraint is that the Caretaker treats the Memento as a black box — it stores but never inspects the internal state.

Memento Implementation

The Memento is an inner class of the Originator, giving it private access to state fields while keeping the Caretaker blind to implementation details.

Java — Game save/undo with Memento
import java.util.ArrayDeque;
import java.util.Deque;

// Originator — the object whose state we want to save/restore
public class GameCharacter {
    private String name;
    private int    health;
    private int    level;
    private String location;

    public GameCharacter(String name) {
        this.name     = name;
        this.health   = 100;
        this.level    = 1;
        this.location = "start";
    }

    // Create a snapshot (Memento)
    public Memento save() {
        return new Memento(health, level, location);
    }

    // Restore from a snapshot
    public void restore(Memento memento) {
        this.health   = memento.health;
        this.level    = memento.level;
        this.location = memento.location;
        System.out.println(name + " restored to: " + this);
    }

    public void takeDamage(int dmg)   { health = Math.max(0, health - dmg); }
    public void gainLevel()           { level++; health = 100; }
    public void moveTo(String loc)    { location = loc; }

    @Override
    public String toString() {
        return String.format("HP=%d, Level=%d, Loc=%s", health, level, location);
    }

    // Memento — inner class has access to private state
    // Caretaker only sees the opaque Memento type, not its fields
    public static final class Memento {
        private final int    health;   // private — Caretaker cannot read
        private final int    level;
        private final String location;

        private Memento(int health, int level, String location) {
            this.health   = health;
            this.level    = level;
            this.location = location;
        }
    }
}

// Caretaker — manages history, never inspects Memento internals
public class GameSaveManager {
    private final Deque<GameCharacter.Memento> history = new ArrayDeque<>();

    public void save(GameCharacter character) {
        history.push(character.save());
        System.out.println("Game saved (" + history.size() + " saves)");
    }

    public void undo(GameCharacter character) {
        if (history.isEmpty()) { System.out.println("No saves to restore"); return; }
        character.restore(history.pop());
    }
}

// Usage
GameCharacter hero = new GameCharacter("Akshay");
GameSaveManager saves = new GameSaveManager();

System.out.println("Initial: " + hero);
saves.save(hero);               // save: HP=100, L=1

hero.moveTo("dungeon");
hero.takeDamage(60);
System.out.println("After fight: " + hero); // HP=40, L=1, dungeon

saves.save(hero);               // save: HP=40, L=1, dungeon
hero.gainLevel();
hero.moveTo("castle");
System.out.println("After level-up: " + hero); // HP=100, L=2, castle

saves.undo(hero);               // restore: HP=40, L=1, dungeon
saves.undo(hero);               // restore: HP=100, L=1, start

Key Points to Remember

  • 1Memento preserves encapsulation — the Caretaker stores but never reads the Memento's state.
  • 2Use a private inner Memento class inside the Originator to restrict access to state fields.
  • 3Memory cost: each Memento stores a full state snapshot — use incremental/delta mementos for large objects.
  • 4Java serialization is an alternative Memento implementation for complex object graphs.
  • 5Undo history = stack of Mementos (push on save, pop on undo).

Interview Questions

Sign in to ask Aria
1

How does Memento maintain encapsulation while saving state?

MediumAmazon
2

What are the memory implications of Memento with deep undo history?

MediumGoogle
3

How would you implement incremental Mementos to reduce memory usage?

HardAdobe
4

What is the role of the Caretaker in Memento pattern?

EasyMicrosoft

Ask Aria about Memento Pattern

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…