Memento — это поведенческий паттерн, который позволяет сохранять и восстанавливать прежнее состояние объекта, не нарушая инкапсуляцию.
Простыми словами: Ctrl+Z в любом редакторе — где-то хранится снимок предыдущего состояния, к которому можно откатиться.
▪️ Пример:
Редактор конфигурации сервера: администратор меняет настройки и может откатиться к любой предыдущей версии.
// Memento — снимок состояния (immutable)
record ConfigMemento(
Map<String, String> properties,
LocalDateTime timestamp
) {
public ConfigMemento {
properties = Map.copyOf(properties); // защитная копия
}
}
// Originator — объект, чьё состояние сохраняем
class ServerConfig {
private final Map<String, String> properties = new HashMap<>();
public void set(String key, String value) {
properties.put(key, value);
}
public String get(String key) {
return properties.get(key);
}
public ConfigMemento save() {
return new ConfigMemento(properties, LocalDateTime.now());
}
public void restore(ConfigMemento memento) {
properties.clear();
properties.putAll(memento.properties());
}
}
// Caretaker — хранит историю снимков
class ConfigHistory {
private final Deque<ConfigMemento> snapshots = new ArrayDeque<>();
public void backup(ServerConfig config) {
snapshots.push(config.save());
}
public void undo(ServerConfig config) {
if (!snapshots.isEmpty()) {
config.restore(snapshots.pop());
}
}
}
// Использование
ServerConfig config = new ServerConfig();
ConfigHistory history = new ConfigHistory();
config.set("maxThreads", "200");
history.backup(config);
config.set("maxThreads", "500");
config.set("timeout", "30s");
history.backup(config);
config.set("maxThreads", "1"); // ой, ошибка
history.undo(config);
System.out.println(config.get("maxThreads")); // 500
▪️ Когда использовать
— Нужна функция отмены/отката (undo)
— Нужно сохранять контрольные точки состояния
— Прямой доступ к полям объекта нарушил бы инкапсуляцию
▪️ Memento vs Command
— Command: хранит действие и умеет его отменить
— Memento: хранит полный снимок состояния
▪️ Минус
Может потреблять много памяти, если состояние объекта большое и снимки создаются часто.
🐸 Библиотека собеса по Java
#patterns