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

Назначение

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

Применимость

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

Структура

Участники

  • Memento - хранитель:
    • сохраняет внутреннее состояние объекта Ordinator. Объем хранимой информации может быть различным и определяется потребностями хозяина;
    • запрещает доступ всем другим объектам, кроме хозяина. По существу, у хранителей есть два интерфейса. "Посыльный" Caretaker "видит" лишь "узкий" интерфейс хранителя - он может только передавать хранителя другим объектам. Напротив, хозяину доступен "широкий" интерфейс, который обеспечивает доступ ко всем данным, необходимым для восстановления в прежнем состоянии. Идеальный вариант - когда только хозяину, создавшему хранитель, открыт доступ к внутреннему состоянию последнего;
  • Ordinator - хозяин:
    • создает хранитель, содержащего снимок текущего внутреннего состояния;
    • использует хранитель для восстановления внутреннего состояния;
  • Caretaker - посыльный:
    • отвечает за сохранение хранителя;
    • не производит никаких операций над хранителем и не исследует его внутреннее содержимое.

Результаты

  • сохранение границ инкапсуляции. Хранитель позволяет избежать раскрытия информации, которой должен распоряжаться только хозяин, но которую тем не менее необходимо хранить вне последнего. Этот паттерн экранирует объекты от потенциально сложного внутреннего устройства хозяина, не изменяя границы инкапсуляции;
  • упрощение структуры хозяина. При других вариантах дизайна, направленного на сохранение границ инкапсуляции, хозяин хранит внутри себя версии внутреннего состояния, которое запрашивали клиенты. Таким образом, вся ответственность за управление памятью лежит на хозяине. При перекладывании заботы о запрошенном состоянии на клиентов упрощается структура хозяина, а клиентам дается возможность не информировать хозяина о том, что они закончили работу;
  • значительные издержки при использовании хранителей. С хранителями могут быть связаны значительные издержки, если хозяин должен копировать большой объем информации для занесения в память хранителя или если клиенты создают и возвращают хранителей достаточно часто. Если плата за инкапсуляцию и восстановление хозяина велика, то этот паттерн не всегда подходит;
  • определение "узкого" и "широкого" интерфейсов. В некоторых языках сложно гарантировать, что только хозяин имеет доступ к состоянию хранителя;
  • скрытая плата за содержание хранителя. Посыльный отвечает за удаление хранителя, однако не располагает информацией о том, какой объем информации о состоянии скрыт в нем. Поэтому не требовательный к ресурсам посыльный может расходовать очень много памяти при работе с хранителем.