Шаблон проектирования Memento

Memento — хранитель, он же — token, лексема. Сохраняет и выносит за пределы объекта его внутреннее состояние, чтобы позднее можно было восстановить объект в сохраненном состоянии.

Самая очевидная сфера применения шаблона Memento — реализация откатов в работе программ.
Например, вы обрабатываете фотографию, применили несколько фильтров, но результат не понравился и вы хотите вернуться на несколько шагов назад — к некому промежуточному результату обработки.

 

Архитектура шаблона Memento


memento_design_pattern
Изображение с сайта https://ru.wikipedia.org

Memento — хранитель — это объект, который сохраняет внутреннее состояние объекта — Originator, Хозяина. Информацию в Хранитель помещает только Хозяин. Информация из Хранителя так же доступна только Хозяину.

Originator — объект «Хозяин». Создает объект-хранитель, по запросу объекта-опекуна, и восстанавливает свое состояние, получая данные из Хранителя.

Caretaker — объект «Опекун». По сути, этот объект является механизмом отката. Он отвечает за хранение созданного Хозяином объекта-хранителя. Сам хозяин может создавать Хранителя, но не сохраняет информации о нем. При необходимости, Опекун передает Хранителя Хозяину, и тот использует его по собственному усмотрению.

Опекун может сохранять информацию о нескольких Хранителях, созданных в разное время, и отвечать за то, чтобы восстановление предыдущего состояния происходило в логичном порядке.

Опекун запрашивает создание Хранителя у Хозяина, и при необходимости, возвращает Хозяину объект-хранитель. Если было создано несколько Хранителей, то Опекун сам решает, какого из Хранителей когда вернуть. При этом, восстановление состояния Хозяина может не потребоваться, например, если измененный вами документ вас полностью устраивает, то вы просто сохраняете его в файл и выходите из программы. Откаты не всегда используются, но должны быть доступны в любой момент.

Иногда, хранение копий состояний объекта «Хозяин» возлагают на самого Хозяина. Это усложняет объект, тем не менее, такие архитектуры существуют и успешно применяются. Правда, подобная архитектура уже не будет относиться к шаблону Memento.

Понимание работы шаблона Memento, хотя бы в общих чертах, будет полезно при попытках разобраться с логикой работы фреймворков для создания асинхронных серверов. Шаблон может и не применяться в асинхронных системах, но сама концепция сохранения промежуточных состояний некоторых объектов, потоков и т.п. — применяется.

 

Пример реализации шаблона проектирования Memento

Хозяин:

Хранитель:

Класс и объект Memento, отвечают за то, чтобы сохранить состояние объекта. Объект — является хранителем в прямом смысле.

Опекун:

Опекун отвечает за хранение экземпляров Хранителей. Кроме того, в случае, когда Хранителей много, Опекун управляет очередностью и логикой их возврата Хозяину.

Использование паттерна:

 

Вариация, на тему использования идеи шаблона Memento

В данном случае Caretaker — это не просто «механизм отката», это скорее менеджер состояний, который управляет тем, какое состояние получит worker в следующий момент. Работа worker-а зависит от того, какое состояние будет ему присвоено.

 

Полезные ссылки по теме шаблона проектирования Memento

perldesignpatterns.com: Memento Pattern

ajc.su: «Хранитель» Memento

github.com: oxnz — Шаблон проектирования Memento, perl

Хранитель (шаблон проектирования)