Посетитель (Visitor) — различия между версиями
Admin (обсуждение | вклад) (→Описание) |
Admin (обсуждение | вклад) (→Участники) |
||
Строка 25: | Строка 25: | ||
==== Участники==== | ==== Участники==== | ||
− | * | + | * Visitor - посетитель |
+ | Объявляет метод Visit... для каждого класса в иерархии объектов с базовым классом Element. Например, для элемента ElementA объявляется метод VisitElementA с параметром типа ElementA. | ||
=== Пример === | === Пример === |
Версия 12:11, 31 июля 2014
Другое название
Назначение
Позволяет выполнить над каждым объектом некоторой структуры операцию, не загрязняя код класса этого объекта и не используя определение типа для каждого объекта.
Описание
Когда есть некоторая полиморфная структура данных (связный список, дерево), и требуется ее обойти, выполнив для каждого узла структуры действие в зависимости от типа узла, то обычной практикой в ООП является создание виртуального метода для этого действия и переопределение его в потомках. Однако, данный подход имеет ряд недостатков. При наличии нескольких типов действий для каждого из них необходимо делать виртуальный метод, что захламляет интерфейс класса.
Одно из решений данной проблемы состоит в том чтобы вынести действие (точнее, группу полиморфных действий) в отдельный объект, называемый Посетителем, и передавать его элементам полиморфной структуры по мере ее обхода. "Принимая" посетителя, элемент посылает ему запрос, соответствующий типу этого элемента. Кроме того, в этом запросе в качестве параметра передается сам элемент.
Таким образом, действия, производимые над объектами полиморфной структуры, являются внешними по отношению к самой этой структуре. Это позволяет, в частности, легко добавлять новые действия за счет реализации подклассов класса Visitor. Исходный код узлов полиморфной структуры остается при этом неизменным.
Паттерн Посетитель является одним из решений так называемой задачи двойной диспетчеризации. В этой задаче требуется выполнять определенное действие от двух параметров: типа объекта и типа операции. По-существу, возникает матрица действий с индексами, являющимися типами: первый индекс определяет тип объекта структуры, второй - тип действия.
Использование
Паттерн Посетитель следует использовать когда
- в структуре присутствуют объекты многих классов, и необходимо выполнять над ними операции в зависимости от типа этих классов;
- нежелательно засорять объекты структуры кодом операций, которые необходимо над ними выполнить
- классы структуры меняются редко, а новые операции над элементами структуры добавляются часто.
Реализация
Диаграмма классов
Участники
- Visitor - посетитель
Объявляет метод Visit... для каждого класса в иерархии объектов с базовым классом Element. Например, для элемента ElementA объявляется метод VisitElementA с параметром типа ElementA.