Skip to content

Latest commit

 

History

History
80 lines (52 loc) · 7 KB

File metadata and controls

80 lines (52 loc) · 7 KB

Посетитель

UML

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

*Проблема раннего и позднего связывания

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

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

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

    • Посетитель позволяет извлечь родственные операции из классов, составляющих структуру объектов, поместив их в один класс-посетитель. Если структура объектов является общей для нескольких приложений, то паттерн позволит в каждое приложение включить только нужные операции.
  • Когда новое поведение имеет смысл только для некоторых классов из существующей иерархии.

    • Посетитель позволяет определить поведение только для этих классов и оставить его пустым для всех остальных.

Шаги реализации

  1. Создайте интерфейс посетителя и объявите в нём методы «посещения» для каждого класса компонента, который существует в программе.

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

  3. Реализуйте методы принятия во всех конкретных компонентах. Они должны переадресовывать вызовы тому методу посетителя, в котором класс параметра совпадает с текущим классом компонента.

  4. Иерархия компонентов должна знать только о базовом интерфейсе посетителей. С другой стороны, посетители будут знать обо всех классах компонентов.

  5. Для каждого нового поведения создайте свой конкретный класс. Приспособьте это поведение для всех посещаемых компонентов, реализовав все методы интерфейса посетителей.

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

  6. Клиент будет создавать объекты посетителей, а затем передавать их компонентам, используя метод принятия.

Преимущества и недостатки

+ -
Упрощает добавление новых операций над всей связанной структурой объектов. Паттерн неоправдан, если иерархия компонентов часто меняется.
Объединяет родственные операции в одном классе. Может привести к нарушению инкапсуляции компонентов.
Посетитель может накоплять состояние при обходе структуры компонентов.

Отношения с другими паттернами

  • Посетитель можно рассматривать как расширенный аналог Команды, который способен работать сразу с несколькими видами получателей.

  • Вы можете выполнить какое-то действие над всем деревом Компоновщика при помощи Посетителя.

  • Посетитель можно использовать совместно с Итератором. Итератор будет отвечать за обход структуры данных, а Посетитель - за выполнение действий над каждым её компонентом.