Перейти к основному содержимому

Что это такое

Паттерн Снимок (Memento) сохраняет слепок состояния объекта, чтобы позже его можно было восстановить, — и при этом не открывает внутреннее устройство объекта никому. Объект сам создаёт снимок и сам восстанавливается из него; внешний мир лишь хранит снимки.

Это тот самый паттерн, который стоит за «откатом к сохранённой точке», черновиками и контрольными точками.


Пример: снимки редактора

save() возвращает снимок; restore() принимает его обратно. Ошибка, сделанная в промежутке, просто исчезает.

Сохранить, испортить, восстановить

Снимок был сделан, пока текст был правильным. После ошибочной правки restore($saved) возвращает в точности прежнее состояние — тот, кто хранил снимок, ни разу не заглянул внутрь него. Снимок — это readonly-класс: созданный однажды, он уже никак не изменится.

Prompt
Напишите PHP-скрипт с паттерном «Снимок» (Memento): класс Editor со свойством text, readonly-класс Snapshot, метод save, возвращающий снимок, и метод restore, принимающий его. Запишите правильный текст, сохраните снимок, внесите ошибочную правку, выведите её, восстановите снимок и выведите возвращённый текст.
Вывод: PHP-скрипт

Когда применять

Применяйте для контрольных точек и откатов: отмена действий в редакторе, сохранения в играх, «восстановить настройки по умолчанию», шаги транзакции, которые может понадобиться отменить.

Не применяйте, когда состояние — это одно-два простых значения: достаточно сохранить старое значение в переменной. И сравните с паттерном «Команда»: команды отменяют действия шаг за шагом, а снимки возвращают сразу к сохранённой точке.


Плюсы и минусы

Плюсы: настоящий откат без раскрытия внутреннего устройства; снимки — это простые значения, которые можно складывать в списки и получить многоуровневую отмену.

Минусы: снимки большого состояния быстро съедают память; решить, что именно входит в снимок (и поддерживать его полноту по мере роста класса), легко сделать неправильно.