The Memento pattern saves an object’s state at one moment so that the object can restore it later. That saved state is called a snapshot. The object decides what to save and how to restore it. Other code can keep the saved snapshot without needing to change the object’s private fields directly.
Use Memento when an application needs to restore an earlier state, such as undoing an edit. In our example, an article creates a snapshot of its text before an edit. Restoring that snapshot brings the earlier text back.
1. How the Memento Pattern Works
Pattern descriptions use three names for the participants. The originator is the object whose state changes. The memento is its saved snapshot. The caretaker keeps snapshots and decides when to request a restore.
Our Article is the originator, Article.Snapshot is the memento, and the calling code is the caretaker. A more complete editor could have a history component that holds several snapshots.
The snapshot is not automatically a backup file or a database transaction. In this example it is an in-memory object. If the process exits, we lose it unless we separately implement durable storage.
Each role has a narrow job:
| Participant | Responsibility |
|---|---|
| Originator | Article owns the text and knows how to save and restore it. |
| Memento | Article.Snapshot holds the saved state. |
| Caretaker | Calling code keeps the snapshot and asks the article to restore it. |
The article saves a snapshot before an edit. Calling code retains it, changes the article, then passes the snapshot back when restoration is needed.
2. Let the Article Create Its Snapshot
Article has one editable value, content. Its save() method captures that value, and restore() applies an earlier snapshot.
The nested Snapshot type exposes no setters or content accessor. Code can hold it, but the article remains responsible for interpreting its contents.
import java.util.Objects;
final class Article {
private String content;
Article(String content) {
this.content = Objects.requireNonNull(content);
}
void write(String content) {
this.content = Objects.requireNonNull(content);
}
String content() {
return content;
}
Snapshot save() {
return new Snapshot(this, content);
}
void restore(Snapshot snapshot) {
if (snapshot.owner != this) {
throw new IllegalArgumentException("Snapshot belongs to another article");
}
content = snapshot.content;
}
static final class Snapshot {
private final Article owner;
private final String content;
private Snapshot(Article owner, String content) {
this.owner = owner;
this.content = content;
}
}
}
Java allows an enclosing class to access the private members of its nested class, as the Java Language Specification describes. That is why Article.restore() can read the snapshot fields, even though the calling code cannot.
The snapshot stores the owner as well as the text. That check prevents a snapshot from one article being restored into another article by mistake. It also means a retained snapshot holds a reference to its article, which matters when deciding how long to keep history.
The text is a String, which is immutable. If the article contained a mutable list, copying only its reference would not preserve the old list contents. We would need a suitable copy or another immutable representation of the saved data.
3. Save, Edit and Restore
Save the import and Article above this entry point in MementoDemo.java.
public class MementoDemo {
public static void main(String[] args) {
Article article = new Article("First draft");
Article.Snapshot beforeEdit = article.save();
article.write("Revised draft");
System.out.println(article.content());
article.restore(beforeEdit);
System.out.println(article.content());
}
}
javac MementoDemo.java
java MementoDemo
Revised draft
First draft
The snapshot is created before the edit. The first output shows the new content, and the second shows that restoration recovered the saved content. The caretaker does not assign private article fields itself.
Restoration only changes the state represented in the snapshot. It cannot retract an email already sent or reverse an external payment. Those actions need their own recovery or compensation policies.
4. Build an Undo History Deliberately
For several undo steps, the caretaker can keep snapshots in a stack. Before an edit, it saves the current state. Undo removes the latest snapshot and asks the article to restore it.
Redo needs another policy. One common arrangement saves the state being left onto a redo stack. A new edit after an undo normally clears the abandoned redo branch. We choose and test those rules instead of assuming that one saved snapshot provides a complete editor history.
History also consumes memory. For a large document, we can cap the number of snapshots, group small edits or store changes rather than full copies. A change-based history still needs enough information to reconstruct or reverse each saved edit. The Command pattern is useful when we want to represent operations and their undo behavior explicitly. Commands can also use mementos internally.
5. Encapsulation and Java Undo APIs
Memento aims to keep responsibility for saving and restoring state with the object that understands it. This is why the example does not give the caretaker public setters for every snapshot field.
A nested type is one way to express that boundary. The pattern does not require one. Package visibility, immutable data types and other arrangements can fit different APIs.
Swing’s UndoManager manages undoable edits. It provides an established undo framework, but its edit model is richer than simply copying this article’s text.
Browse the complete Memento example on GitHub to compile and run it locally.
6. Conclusion
Memento gives an object a controlled way to save and restore its state. A useful implementation defines what the snapshot includes, prevents accidental mutation and gives history a clear lifetime. Durability, redo and external side effects remain separate design decisions.
Hi!
Nice article but it doesn’t show the real importance of memento, which is returning to any previous state. this will only return to the last previous state.
another better approach is to maintain a stack in the care taker class that saves every memento object
Thanks for the suggestion.