
Пример сохранения снимков состояния текстового редактора.
Объекты команд выступают в роли опекунов и запрашивают снимки у редактора перед тем, как выполнить своё действие. Если потребуется отмена операции, команда сможет восстановить состояние редактора, используя сохранённый снимок.
При этом снимок не имеет публичных полей, поэтому никакой объект не сможет получить доступа его данным. Снимки связаны с определённым редактором, которых их создал и сам восстанавливает его состояние. Это позволяет программе иметь одновременно несколько объектов редакторов, например, разбитых по вкладкам.
Когда вам нужно сохранять мгновенный снимок состояния объекта (или его части), чтобы впоследствии объект можно было восстановить в том же состоянии.
Паттерн Снимок позволяет делать любое количество снимков объекта и хранить их независимо от объекта, с которого делают снимок. Снимки часто используют не только для реализации операции отмены, но и для транзакций, когда состояние объекта нужно откатить, если операция не удалась.
Когда прямое получение состояния объекта раскрывает детали его реализации и нарушает инкапсуляцию.
Паттерн предлагает изготовить снимок самому исходному объекту, так как ему доступны все поля, даже приватные.
Определите класс создателя, объекты которого должны создавать снимки своего состояния.
Создайте класс снимка и опишите в нём все те же поля, которые имеются в оригинальном классе-создателе.
Сделайте объекты снимков неизменяемыми. Они должны получать начальные значения только один раз, через свой конструктор.
Если ваш язык программирования это позволяет, сделайте класс снимка вложенным в класс создателя.
Если нет, извлеките из класса снимка пустой интерфейс, который будет доступен остальным объектам программы. Впоследствии вы можете добавить некоторые вспомогательные методы в этот интерфейс, дающие доступ к метаданным снимка, однако прямой доступ к данным создателя должен быть исключён.
Добавьте в класс создателя метод получения снимков. Создатель должен создавать новые объекты снимков, передавая значения своих полей через конструктор.
Сигнатура метода должна возвращать снимки через ограниченный интерфейс, если он у вас есть. Сам класс должен работать с конкретным классом снимка.
Добавьте в класс создателя метод восстановления из снимка. Что касается привязки к типам, руководствуйтесь той же логикой, что и в пункте 4.
Опекуны, будь то история операций, объекты команд или нечто иное, должны знать о том, когда запрашивать снимки у создателя, где их хранить, и когда восстанавливать.
Связь опекунов с создателями можно перенести внутрь снимков. В этом случае каждый снимок будет привязан к своему создателю и должен будет сам восстанавливать его состояние. Но это будет работать либо если классы снимков вложены в классы создателей, либо если создатели имеют сеттеры для установки значений своих полей.
и можно использовать сообща для реализации отмены операций. В этом случае объекты команд будут отображать выполненные действие над объектом, снимки — хранить копию состояния этого объекта до того, как команда была выполнена.
можно использовать вместе с , чтобы сохранить текущее состояние обхода структуры данных и вернуться к нему в будущем, если потребуется.
иногда можно заменить , если объект, чьё состояние требуется сохранять в истории, довольно простой, не имеет активных ссылок на внешние ресурсы, либо их можно легко восстановить.