Memento Pattern
1. Introduction
The Memento Pattern is a behavioral design pattern that allows an object to capture and store its internal state without exposing its implementation details. This pattern is particularly useful for undo/redo functionality, state restoration, and data recovery.
2. Key Concepts
- Memento: An object that stores the internal state of the originator.
- Originator: The object whose state needs to be saved and restored.
- Caretaker: An object that manages the memento and is responsible for saving and restoring the state.
3. Definition
The Memento Pattern provides a way to capture an object's state so that it can be restored later without violating encapsulation. This means that the memento can only be accessed by the originator, ensuring the internal state is not exposed to other objects.
4. Implementation
4.1. Class Diagram
class Originator {
private state: string;
createMemento(): Memento {
return new Memento(state);
}
restore(memento: Memento): void {
this.state = memento.getState();
}
}
class Memento {
private state: string;
constructor(state: string) {
this.state = state;
}
getState(): string {
return state;
}
}
class Caretaker {
private mementos: Memento[] = [];
addMemento(memento: Memento): void {
mementos.push(memento);
}
getMemento(index: number): Memento {
return mementos[index];
}
}
4.2. Code Example
class TextEditor {
private content: string = '';
setText(text: string) {
this.content = text;
}
save(): Memento {
return new Memento(this.content);
}
restore(memento: Memento) {
this.content = memento.getState();
}
}
class Memento {
private state: string;
constructor(state: string) {
this.state = state;
}
getState(): string {
return this.state;
}
}
class Caretaker {
private mementos: Memento[] = [];
addMemento(memento: Memento) {
this.mementos.push(memento);
}
getMemento(index: number): Memento {
return this.mementos[index];
}
}
// Usage
const editor = new TextEditor();
const caretaker = new Caretaker();
editor.setText("First version");
caretaker.addMemento(editor.save());
editor.setText("Second version");
caretaker.addMemento(editor.save());
editor.restore(caretaker.getMemento(0)); // Restores to "First version"
5. Best Practices
- Keep the memento class simple and focused on storing state.
- Ensure the memento can only be accessed by the originator.
- Limit the number of mementos stored to avoid excessive memory usage.
6. FAQ
What is the primary use case for the Memento Pattern?
The primary use case is to implement undo/redo functionality in applications, allowing users to revert to previous states without exposing internal details of the objects.
Can the Memento Pattern be used in multi-threaded applications?
Yes, but care must be taken to synchronize access to the mementos to prevent inconsistencies and data corruption.