Посетитель (шаблон проектирования)

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Шаблон проектирования
Посетитель
Visitor
Тип: поведенческий
Назначение: не изменяя основного класса, добавить в него новые операции.
Структура: VisitorDiagram.svg
Применяется в случаях: когда необходимо для ряда классов сделать похожую (одну и ту же) операцию.
Плюсы:
  • новая функциональность в несколько классов добавляется сразу, не изменяя код этих классов;
  • позволяет получить информацию о типе объекта;
  • двойная диспетчеризация;
  • возможность описания своего алгоритма для каждого типа объектов.
Минусы:
  • при изменении обслуживаемого класса нужно поменять код у шаблона;
  • затруднено добавление новых классов, поскольку нужно обновлять иерархию посетителя и его сыновей.
  • Описан в Design Patterns Да

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

    Шаблон демонстрирует классический приём восстановления информации о потерянных типах, не прибегая к понижающему приведению типов при помощи двойной диспетчеризации.

    Решаемая проблема[править | править код]

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

    Задача[править | править код]

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

    Решение[править | править код]

    Для независимости посетитель имеет отдельную иерархию. Структуры имеют некий интерфейс взаимодействия.

    Использование[править | править код]

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

    Создается базовый класс Visitor с методами visit() для каждого подкласса родительского Element. Добавьте метод accept(visitor) в иерархию Element. Для каждой операции, которая должна выполняться для объектов Element, создайте производный от Visitor класс. Реализации метода visit() должны использовать открытый интерфейс класса Element. В результате: клиенты создают объекты Visitor и передают их каждому объекту Element, вызывая accept().

    Рекомендации[править | править код]

    Шаблон следует использовать, если:

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

    Преимущества и недостатки[править | править код]

    Преимущества:

    • упрощается добавление новых операций;
    • объединение родственных операции в классе Visitor;
    • класс Visitor может запоминать в себе какое-то состояние по ходу обхода контейнера.

    Недостатки:

    • затруднено добавление новых классов, поскольку нужно обновлять иерархию посетителя и его сыновей.

    Реализация[править | править код]

    1. Добавьте метод accept(Visitor) в иерархию «элемент».
    2. Создайте базовый класс Visitor и определите методы visit() для каждого типа элемента.
    3. Создайте производные классы Visitor для каждой операции, исполняемой над элементами.
    4. Клиент создаёт объект Visitor и передаёт его в вызываемый метод accept().

    C++[править | править код]

    Java[править | править код]

    C#[править | править код]

    PHP[править | править код]

    Python[править | править код]

    Литература[править | править код]

    • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования. — СПб: Питер, 2001. — 368 с. — ISBN 5-272-00355-1.

    Ссылки[править | править код]