Что это такое
Паттерн Снимок (Memento) сохраняет слепок состояния объекта, чтобы позже его можно было восстановить, — и при этом не открывает внутреннее устройство объекта никому. Объект сам создаёт снимок и сам восстанавливается из него; внешний мир лишь хранит снимки.
Это тот самый паттерн, который стоит за «откатом к сохранённой точке», черновиками и контрольными точками.
Пример: снимки редактора
save() возвращает снимок; restore() принимает его обратно. Ошибка, сделанная в промежутке, просто исчезает.
Сохранить, испортить, восстановить
Снимок был сделан, пока текст был правильным. После ошибочной правки restore($saved) возвращает в точности прежнее состояние — тот, кто хранил снимок, ни разу не заглянул внутрь него. Снимок — это readonly-класс: созданный однажды, он уже никак не изменится.
Вывод: PHP-скрипт
<?php
// Снимок (memento): зафиксированный слепок состояния.
final readonly class Snapshot {
public function __construct(public string $text) {}
}
class Editor {
public string $text = "";
public function save(): Snapshot {
return new Snapshot($this->text);
}
public function restore(Snapshot $snapshot): void {
$this->text = $snapshot->text;
}
}
$editor = new Editor();
$editor->text = "Hello, world!";
$saved = $editor->save();
$editor->text = "Hello, wrold! oops";
echo "сейчас: ", $editor->text, "\n";
$editor->restore($saved);
echo "отмена: ", $editor->text, "\n";
Когда применять
Применяйте для контрольных точек и откатов: отмена действий в редакторе, сохранения в играх, «восстановить настройки по умолчанию», шаги транзакции, которые может понадобиться отменить.
Не применяйте, когда состояние — это одно-два простых значения: достаточно сохранить старое значение в переменной. И сравните с паттерном «Команда»: команды отменяют действия шаг за шагом, а снимки возвращают сразу к сохранённой точке.
Плюсы и минусы
Плюсы: настоящий откат без раскрытия внутреннего устройства; снимки — это простые значения, которые можно складывать в списки и получить многоуровневую отмену.
Минусы: снимки большого состояния быстро съедают память; решить, что именно входит в снимок (и поддерживать его полноту по мере роста класса), легко сделать неправильно.