Memento Design Pattern (original) (raw)

Last Updated : 3 Jun, 2026

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.

**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.

client_user_

In the above diagram

Components

The Memento Design Pattern consists of the following key components that work together to save and restore an object’s state.

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.

Working

The pattern works by capturing and restoring an object’s state using memento objects.

originator

Uses

The Memento pattern is commonly used where state rollback is required.

Communication between the components

The components of the Memento Pattern interact together to save and restore an object’s state efficiently.

caretaker

  1. **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."
  2. **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).
  3. **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

1-(1)

Class Diagram

Let’s break down into the component wise code:

1. **Originator (Document)

C++ `

#include #include

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 createMemento() { return std::make_shared(content); } void restoreFromMemento(const std::shared_ptr& memento) { content = memento->getSavedContent(); } };

Java

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();
}

}

Python

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()

JavaScript

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

C++ `

#include

class DocumentMemento { private: std::string content;

public: DocumentMemento(std::string content) : content(content) {}

std::string getSavedContent() {
    return content;
}

};

Java

public class DocumentMemento { private String content;

public DocumentMemento(String content) {
    this.content = content;
}

public String getSavedContent() {
    return this.content;
}

}

Python

class DocumentMemento: def init(self, content): self.content = content

def get_saved_content(self):
    return self.content

JavaScript

class DocumentMemento { constructor(content) { this.content = content; }

getSavedContent() {
    return this.content;
}

}

`

3. **Caretaker (History)

C++ `

#include #include "DocumentMemento.h"

class History { private: std::vector mementos;

public: History() {}

void addMemento(DocumentMemento memento) {
    mementos.push_back(memento);
}

DocumentMemento getMemento(int index) {
    return mementos[index];
}

};

Java

import java.util.ArrayList; import java.util.List;

public class History { private List 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);
}

}

Python

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]

JavaScript

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:

C++ `

#include #include #include

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 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;

}

Java

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 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());
}

}

Python

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())

JavaScript

// 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.

Disadvantages

Despite its usefulness, the pattern has some limitations.