Обзор темы [Шаблоны проектирования]

Затем: МотивацияНазначение

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

Затем: СтруктураМотивация

Часто приходится сохранять внутреннее состояние объекта. Это требуется при реализации контрольных точек и механизмов отмены операций , восстановления состояния после возникновения ошибок и т.д. Вы должны сохранить информацию о состоянии где-нибудь так, чтобы Вы могли привести их в это состояние позднее. Но объекты обычно инкапсулируют некоторые или все аспекты своего состояния, делая их недоступными другим объектам, т.е. их невозможно сохранить извне. Демонстрация этих аспектов нарушает инкапсуляцию, что может поставить под угрозу надежность и расширяемость.

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

Известный способ поддержки отношения “связь” между объектами – система “ограничений – решений” (ConstrainSolving). Мы можем инкапсулировать эту обязанность в ConstraintSolver. ConstraintSolver фиксирует связи, как только они сделаны и генерирует математические уравнения, которые описывающие эти связи. Он решает эти уравнения когда пользователь делает соединение или изменяет рисунок. ConstraintSolver использует результаты вычислений, чтобы отобразить на графике соответствующие соединения.

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

Вообще, общий интерфейс ConstraintSolver-а мог быть недостаточным, для точной отмены его воздействий на другие объекты. Механизм отмены должен работать с ConstraintSolver боле тесно, но мы должны избежать нарушения инкапсуляции ConstriantSolver-а.

Мы можем решать эту задачу применив шаблон “Сувенир”. A memento - объект, который сохраняет кадр внутренненего состояния другого объекта — создателя (originator). Механизм отмены запросит сувенир у создателя когда потребуется реализовать контрольную точку в состоянии создателя. Создатель инициализирует сувенир(memento) с информацией, характеризующей его текущее состояние. Только создатель может сохранять и изымать информацию из memento - сувенир "непрозрачен" для других объектов.

В примере графического редактора, ConstraintSolver может выполнять роль создателя. Следующая последовательность событий характеризует процесс undo:

  1. Редактор запрашивает сувенир из ConstraintSolver как побочный эффект при выполнении операции перемещения.
  2. ConstraintSolver создает и возвращает сувенир, в данном случае экземпляр SolverState. SolverState содержит структуры данных, которые описывают текущее состояние уравнений и переменных ConstraintSolver.
  3. Позже, когда пользователь отменяет операцию перемещения, редактор отдает SolverState обратно ConstraintSolver-у.
  4. Базирующийся на информации в SolverState, ConstraintSolver изменяет свои внутренние структуры, чтобы возвратить свои уравнения и переменные в их точное предыдущее состояние.

Это соглашение позволяет ConstraintSolver передавать другим объектам информацию, которая требуется для возвращения к предыдущему состоянию без демонстрирования его внутренней структуры и представления.

 

Затем: Составные частиСтруктура

Составные части