The Memento Design Pattern is a behavioral design pattern that allows an object’s state to be saved and restored without exposing its internal structure. It works like taking a snapshot of an object at a particular moment in time. This pattern is commonly used to implement undo and redo functionality in applications.
- Saves and restores an object’s state using memento objects without violating encapsulation.
- Supports undo, rollback, and checkpoint operations during program execution.
Example: A text editor saves snapshots of the document whene ver the user types or edits content. When the user presses Undo, the editor restores the document to a previously saved state.

In the above diagram
- The document acts as the Originator whose state needs to be saved.
- Snapshots of the document are stored as Memento objects in history.
- Pressing Undo restores the document to a previous saved state without exposing internal details.
Components
The Memento Design Pattern consists of the following key components that work together to save and restore an object’s state.
- Originator: The Originator is the object whose state needs to be saved and restored. It creates Memento objects to store its current state and uses them later to restore that state. The Originator communicates directly with the Memento to create and retrieve snapshots.
- Memento: The Memento stores the internal state of the Originator at a specific point in time. It does not allow direct modification of the stored state, ensuring encapsulation and data safety.
- Caretaker: The Caretaker manages and keeps track of Memento objects. It does not know the internal details of the stored state but requests Mementos to save or restore the Originator’s state.
- Client: The Client interacts with the Originator and Caretaker. It initiates requests to save or restore the Originator’s state to achieve the required functionality.
Real-Life Example
The Memento Design Pattern is commonly used in applications where an object’s previous state needs to be saved and restored later.
- Text Editor Undo Feature: When you type or delete text, the editor saves snapshots of the document’s state. Pressing Undo restores the document to a previous state using the saved snapshot.
- Game Save and Load System: In video games, the current progress (player position, score, level, inventory, etc.) is saved as a snapshot. When the player loads the game, it restores the game to that previously saved state without exposing the internal details of how the data is stored.
Working
The pattern works by capturing and restoring an object’s state using memento objects.
- The Originator creates a Memento containing its current state.
- The Caretaker stores the Memento without knowing its internal details.
- When needed, the Caretaker returns the Memento to the Originator.
- The Originator restores its state from the Memento.

- The caretaker calls the createMemento() method on the originator asking the originator to pass it a memento object.
- At this point the originator creates a memento object saving its internal state and passes the memento to the caretaker.
- The caretaker maintains the memento object and performs the operation. In case of the need to undo the operation, the caretaker calls the setMemento() method on the originator passing the maintained memento object.
- The originator would accept the memento, using it to restore its previous state.
Uses
The Memento pattern is commonly used where state rollback is required.
- Undo and redo functionality in text editors.
- Saving game progress and checkpoints.
- Transaction rollback systems.
- Version history management in applications.
Communication between the components
The components of the Memento Pattern interact together to save and restore an object’s state efficiently.

- Client: The client initiates the process by requesting the Originator to perform some operation that may modify its state or require the state to be saved. For example, the client might trigger an action like "save state" or "restore state."
- Originator: The Originator either produces a Memento to save its current state (if the request is to save state) or retrieves a Memento to restore its prior state (if the request is to restore state).
- Caretaker: The Caretaker acts as an intermediary between the client and the Originator, managing the Memento objects.
Implementation Example
Problem Statement
Consider creating a text editor application and want to include an undo feature that lets revert changes made to a document. The difficulty is in storing the document's state at different times and restoring it when required without disclosing the document's internal implementation.
Benefits of Using Memento Pattern in this scenario
- Encapsulation: By using the Memento pattern, you can prohibit direct access to and manipulation of the document's state by encapsulating it within Memento objects.
- Undo Functionality: The Memento pattern makes it possible to construct an undo feature that lets users undo changes and recover earlier document states by saving snapshots of the document's state at various points in time.
- Separation of Concerns: By separating state management responsibilities from the document itself, the Memento design encourages code that is clearer and easier to maintain.
.webp)
Let’s break down into the component wise code:
1. Originator (Document)
#include <string>
#include <memory>
class DocumentMemento {
private:
std::string savedContent;
public:
DocumentMemento(const std::string& content) : savedContent(content) {}
std::string getSavedContent() const { return savedContent; }
};
class Document {
private:
std::string content;
public:
Document(const std::string& content) : content(content) {}
void write(const std::string& text) { content += text; }
std::string getContent() const { return content; }
std::shared_ptr<DocumentMemento> createMemento() { return std::make_shared<DocumentMemento>(content); }
void restoreFromMemento(const std::shared_ptr<DocumentMemento>& memento) { content = memento->getSavedContent(); }
};
public class Document {
private String content;
public Document(String content) {
this.content = content;
}
public void write(String text) {
this.content += text;
}
public String getContent() {
return this.content;
}
public DocumentMemento createMemento() {
return new DocumentMemento(this.content);
}
public void restoreFromMemento(DocumentMemento memento) {
this.content = memento.getSavedContent();
}
}
class DocumentMemento:
def __init__(self, content):
self.saved_content = content
def get_saved_content(self):
return self.saved_content
class Document:
def __init__(self, content):
self.content = content
def write(self, text):
self.content += text
def get_content(self):
return self.content
def create_memento(self):
return DocumentMemento(self.content)
def restore_from_memento(self, memento):
self.content = memento.get_saved_content()
class DocumentMemento {
constructor(content) {
this.savedContent = content;
}
getSavedContent() {
return this.savedContent;
}
}
class Document {
constructor(content) {
this.content = content;
}
write(text) {
this.content += text;
}
getContent() {
return this.content;
}
createMemento() {
return new DocumentMemento(this.content);
}
restoreFromMemento(memento) {
this.content = memento.getSavedContent();
}
}
2. Memento
#include <string>
class DocumentMemento {
private:
std::string content;
public:
DocumentMemento(std::string content) : content(content) {}
std::string getSavedContent() {
return content;
}
};
public class DocumentMemento {
private String content;
public DocumentMemento(String content) {
this.content = content;
}
public String getSavedContent() {
return this.content;
}
}
class DocumentMemento:
def __init__(self, content):
self.content = content
def get_saved_content(self):
return self.content
class DocumentMemento {
constructor(content) {
this.content = content;
}
getSavedContent() {
return this.content;
}
}
3. Caretaker (History)
#include <vector>
#include "DocumentMemento.h"
class History {
private:
std::vector<DocumentMemento> mementos;
public:
History() {}
void addMemento(DocumentMemento memento) {
mementos.push_back(memento);
}
DocumentMemento getMemento(int index) {
return mementos[index];
}
};
import java.util.ArrayList;
import java.util.List;
public class History {
private List<DocumentMemento> mementos;
public History() {
this.mementos = new ArrayList<>();
}
public void addMemento(DocumentMemento memento) {
this.mementos.add(memento);
}
public DocumentMemento getMemento(int index) {
return this.mementos.get(index);
}
}
from typing import List
class DocumentMemento:
pass
class History:
def __init__(self):
self.mementos: List[DocumentMemento] = []
def addMemento(self, memento: DocumentMemento):
self.mementos.append(memento)
def getMemento(self, index: int) -> DocumentMemento:
return self.mementos[index]
class DocumentMemento {
// DocumentMemento implementation
}
class History {
constructor() {
this.mementos = [];
}
addMemento(memento) {
this.mementos.push(memento);
}
getMemento(index) {
return this.mementos[index];
}
}
Complete code for the above example
The complete code for the above example is:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Memento
class DocumentMemento {
private:
string content;
public:
DocumentMemento(string content) {
this->content = content;
}
string getSavedContent() {
return this->content;
}
};
// Originator
class Document {
private:
string content;
public:
Document(string content) {
this->content = content;
}
void write(string text) {
this->content += text;
}
string getContent() {
return this->content;
}
DocumentMemento createMemento() {
return DocumentMemento(this->content);
}
void restoreFromMemento(DocumentMemento memento) {
this->content = memento.getSavedContent();
}
};
// Caretaker
class History {
private:
vector<DocumentMemento> mementos;
public:
void addMemento(DocumentMemento memento) {
mementos.push_back(memento);
}
DocumentMemento getMemento(int index) {
return mementos[index];
}
};
int main() {
Document document("Initial content\n");
History history;
// Save initial state
history.addMemento(document.createMemento());
// Write some content
document.write("Additional content\n");
history.addMemento(document.createMemento());
// Write more content
document.write("More content\n");
cout << "Current Content:\n";
cout << document.getContent() << endl;
// Restore previous state
document.restoreFromMemento(history.getMemento(1));
cout << "After Restore:\n";
cout << document.getContent() << endl;
return 0;
}
import java.util.ArrayList;
import java.util.List;
// Originator
class Document {
private String content;
public Document(String content) {
this.content = content;
}
public void write(String text) {
this.content += text;
}
public String getContent() {
return this.content;
}
public DocumentMemento createMemento() {
return new DocumentMemento(this.content);
}
public void restoreFromMemento(DocumentMemento memento) {
this.content = memento.getSavedContent();
}
}
// Memento
class DocumentMemento {
private String content;
public DocumentMemento(String content) {
this.content = content;
}
public String getSavedContent() {
return this.content;
}
}
// Caretaker
class History {
private List<DocumentMemento> mementos;
public History() {
this.mementos = new ArrayList<>();
}
public void addMemento(DocumentMemento memento) {
this.mementos.add(memento);
}
public DocumentMemento getMemento(int index) {
return this.mementos.get(index);
}
}
public class Main {
public static void main(String[] args) {
Document document = new Document("Initial content\n");
History history = new History();
// Write some content
document.write("Additional content\n");
history.addMemento(document.createMemento());
// Write more content
document.write("More content\n");
history.addMemento(document.createMemento());
// Restore to previous state
document.restoreFromMemento(history.getMemento(1));
// Print document content
System.out.println(document.getContent());
}
}
# Originator
class Document:
def __init__(self, content):
self.content = content
def write(self, text):
self.content += text
def get_content(self):
return self.content
def create_memento(self):
return DocumentMemento(self.content)
def restore_from_memento(self, memento):
self.content = memento.get_saved_content()
# Memento
class DocumentMemento:
def __init__(self, content):
self.content = content
def get_saved_content(self):
return self.content
# Caretaker
class History:
def __init__(self):
self.mementos = []
def add_memento(self, memento):
self.mementos.append(memento)
def get_memento(self, index):
return self.mementos[index]
if __name__ == "__main__":
document = Document("Initial content\n")
history = History()
# Write some content
document.write("Additional content\n")
history.add_memento(document.create_memento())
# Write more content
document.write("More content\n")
history.add_memento(document.create_memento())
# Restore to previous state
document.restore_from_memento(history.get_memento(1))
# Print document content
print(document.get_content())
// Originator
class Document {
constructor(content) {
this.content = content;
}
write(text) {
this.content += text;
}
getContent() {
return this.content;
}
createMemento() {
return new DocumentMemento(this.content);
}
restoreFromMemento(memento) {
this.content = memento.getSavedContent();
}
}
// Memento
class DocumentMemento {
constructor(content) {
this.content = content;
}
getSavedContent() {
return this.content;
}
}
// Caretaker
class History {
constructor() {
this.mementos = [];
}
addMemento(memento) {
this.mementos.push(memento);
}
getMemento(index) {
return this.mementos[index];
}
}
// Main
const document = new Document("Initial content\n");
const history = new History();
// Write some content
document.write("Additional content\n");
history.addMemento(document.createMemento());
// Write more content
document.write("More content\n");
history.addMemento(document.createMemento());
// Restore to previous state
document.restoreFromMemento(history.getMemento(1));
// Print document content
console.log(document.getContent());
Output
Initial content Additional content More content
Advantages
This pattern safely manages object state without exposing internal details.
- Preserves encapsulation of the object’s internal state.
- Supports undo and rollback functionality.
- Simplifies state restoration.
- Allows saving checkpoints of an object’s state.
Disadvantages
Despite its usefulness, the pattern has some limitations.
- Can consume a lot of memory if many states are stored.
- Managing a large number of Mementos can be complex.
- Performance may degrade for large or frequent state saves.