You need to save and restore an object's state without exposing its internal structure. Memento captures the state in an opaque snapshot, the originator creates/restores from mementos, and the caretaker manages the history.
// ─── EXAMPLE 1 ──────────────────────────────────────────────────────────────
// WHAT WE ARE IMPLEMENTING:
// A graphical canvas history buffer saving intermediate drafts to enable
// instant Ctrl-Z restores.
//
// WHERE THE MEMENTO FITS IN:
// CanvasState acts as the Memento storing values. CanvasEditor is the
// Originator whose internal state changes. History represents the Caretaker
// tracking history.
// ────────────────────────────────────────────────────────────────────────────
import java.util.ArrayDeque;
import java.util.Deque;
// --- Memento (opaque snapshot) ---
class EditorMemento {
private final String content;
private final int cursorPosition;
EditorMemento(String content, int cursorPosition) {
this.content = content;
this.cursorPosition = cursorPosition;
}
String getContent() { return content; }
int getCursorPosition() { return cursorPosition; }
}
// --- Originator ---
class TextEditor {
private String content = "";
private int cursorPosition = 0;
public void write(String text) {
content += text;
cursorPosition = content.length();
}
public void deleteLast(int chars) {
if (content.length() >= chars) {
content = content.substring(0, content.length() - chars);
cursorPosition = content.length();
}
}
// Save state to memento
public EditorMemento save() {
return new EditorMemento(content, cursorPosition);
}
// Restore state from memento
public void restore(EditorMemento memento) {
this.content = memento.getContent();
this.cursorPosition = memento.getCursorPosition();
}
public String getContent() { return content; }
}
// --- Caretaker ---
class EditorHistory {
private final Deque<EditorMemento> history = new ArrayDeque<>();
public void push(EditorMemento memento) {
history.push(memento);
}
public EditorMemento pop() {
return history.isEmpty() ? null : history.pop();
}
}
public class Main {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
EditorHistory history = new EditorHistory();
editor.write("Hello ");
history.push(editor.save());
editor.write("World!");
history.push(editor.save());
editor.write(" This is extra.");
System.out.println("Current: " + editor.getContent());
// Undo twice
EditorMemento restored = history.pop();
if (restored != null) editor.restore(restored);
System.out.println("Undo 1: " + editor.getContent());
restored = history.pop();
if (restored != null) editor.restore(restored);
System.out.println("Undo 2: " + editor.getContent());
}
}