Позволяет создавать новые операции, не меняя классы объектов, над которыми эти операции могут выполняться.
*Проблема раннего и позднего связывания
-
Когда вам нужно выполнить операцию над всеми элементами сложной структуры объектов (например, деревом).
- Посетитель позволяет применять одну и ту же операцию к объектам различных классов.
-
Когда над объектами сложной структуры объектов надо выполнять некоторые, не связанные между собой операций, но вы не хотите «засорять» классы такими операциями.
- Посетитель позволяет извлечь родственные операции из классов, составляющих структуру объектов, поместив их в один класс-посетитель. Если структура объектов является общей для нескольких приложений, то паттерн позволит в каждое приложение включить только нужные операции.
-
Когда новое поведение имеет смысл только для некоторых классов из существующей иерархии.
- Посетитель позволяет определить поведение только для этих классов и оставить его пустым для всех остальных.
-
Создайте интерфейс посетителя и объявите в нём методы «посещения» для каждого класса компонента, который существует в программе.
-
Опишите интерфейс компонентов. Если вы работаете с уже существующими классами, то объявите абстрактный метод принятия посетителей в базовом классе иерархии компонентов.
-
Реализуйте методы принятия во всех конкретных компонентах. Они должны переадресовывать вызовы тому методу посетителя, в котором класс параметра совпадает с текущим классом компонента.
-
Иерархия компонентов должна знать только о базовом интерфейсе посетителей. С другой стороны, посетители будут знать обо всех классах компонентов.
-
Для каждого нового поведения создайте свой конкретный класс. Приспособьте это поведение для всех посещаемых компонентов, реализовав все методы интерфейса посетителей.
Вы можете столкнуться с ситуацией, когда посетителю нужен будет доступ к приватным полям компонентов. В этом случае, вы можете либо раскрыть доступ к этим полям, нарушив инкапсуляцию компонентов, либо сделать класс посетителя вложенным в класс компонента, если вам повезло писать на языке, который поддерживает вложенность классов.
-
Клиент будет создавать объекты посетителей, а затем передавать их компонентам, используя метод принятия.
| + | - |
|---|---|
| Упрощает добавление новых операций над всей связанной структурой объектов. | Паттерн неоправдан, если иерархия компонентов часто меняется. |
| Объединяет родственные операции в одном классе. | Может привести к нарушению инкапсуляции компонентов. |
| Посетитель может накоплять состояние при обходе структуры компонентов. |
-
Посетитель можно рассматривать как расширенный аналог Команды, который способен работать сразу с несколькими видами получателей.
-
Вы можете выполнить какое-то действие над всем деревом Компоновщика при помощи Посетителя.
-
Посетитель можно использовать совместно с Итератором. Итератор будет отвечать за обход структуры данных, а Посетитель - за выполнение действий над каждым её компонентом.
