Skip to content
DevPedia

Behavioral patternsGuide 22 of 28

Memento

How to save and restore an object's state without exposing its internal details.

Updated 6 min read

Also known as: Snapshot

Memento is a behavioral pattern that lets you save and restore an object’s previous state without exposing its implementation details.

The problem

In the admin panel, an order in draft status can be edited several times before being confirmed: adding or removing products, changing the address, adjusting quantities. The support team wants to be able to undo those edits and go back to an earlier version of the draft. Saving the state by accessing Order’s private fields from outside breaks its encapsulation — and any future change to Order’s internal structure would force an update to the code that saves and restores it too.

The solution

Memento leaves capturing the state to the object that owns it: Order is the one that knows how to create a snapshot of itself (OrderMemento) and how to restore itself from an earlier snapshot. The draft history stores those snapshots, but never looks at or modifies their contents — it only passes them back and forth when an undo is needed.

The structure of Memento: the originator creates and reads the memento; the caretaker only stores and returns it, with no way to inspect it.

Example in Java

// The Memento: immutable, only Order knows how to interpret it
class OrderMemento {
    private final List<Item> items;
    private final String address;

    OrderMemento(List<Item> items, String address) {
        this.items = List.copyOf(items);
        this.address = address;
    }
}

class Order {
    private List<Item> items = new ArrayList<>();
    private String address;

    public OrderMemento save() {
        return new OrderMemento(items, address);
    }

    public void restore(OrderMemento memento) {
        this.items = new ArrayList<>(memento.items);
        this.address = memento.address;
    }

    public void addItem(Item item) { items.add(item); }
    public void setAddress(String address) { this.address = address; }
}

// The Caretaker: it stores mementos, without ever looking at their contents
class OrderHistory {
    private final Deque<OrderMemento> snapshots = new ArrayDeque<>();

    public void push(OrderMemento memento) {
        snapshots.push(memento);
    }

    public OrderMemento pop() {
        return snapshots.pop();
    }
}
Order draft = new Order();
OrderHistory history = new OrderHistory();

draft.addItem(jacket);
history.push(draft.save()); // stores the starting point

draft.setAddress("wrong address");
// ...if an undo is needed:
draft.restore(history.pop());

When to use it

  • When you need to be able to undo changes on an object without exposing its internal details to the code managing the history.
  • When capturing the state directly from outside would break the object’s encapsulation.

When to avoid it

Storing mementos of very large or frequently changing objects can consume a lot of memory — you have to weigh how many snapshots will pile up.

Benefits and drawbacks

BenefitsDrawbacks
Lets you undo changes without breaking the original object’s encapsulationStoring many mementos of large objects can consume a lot of memory
The history doesn’t need to know the internal structure of the object it backs upYou have to decide explicitly when to take each snapshot: one per keystroke is expensive; one per “save” can be too late

Relationship with other patterns

  • It’s often used alongside Command to implement undo(): the Command stores a Memento before running, and uses it to revert.
  • It differs from Prototype in that Memento captures state to restore it onto the same object later, while Prototype creates a new and independent object from an existing one.

Share this guide

Search by concept, pattern or practice.