Krasorion.ru

Упаковочные материалы

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

Шаблон проектирования
Посетитель
Visitor
Тип:

поведенческий

Описан в Design Patterns

Да

Шаблон Посетитель (Visitor) — поведенческий Шаблон проектирования.

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

Содержание

Описание средствами псевдокода

interface Obj
{
    void visit(Visitor visitor, params);
}
 
interface Visitor
{
    void visitA(A a, params);
    void visitB(B b, params);
} 
 
class A implements Obj
{
    void visit(Visitor visitor, params) { visitor.visitA(this, params); }
}
 
class B implements Obj
{
    void visit(Visitor visitor, params) { visitor.visitB(this, params); }
}
 
class Visitor1 implements Visitor
{
    void visitA(A a, params);
    void visitB(B b, params);
}
 
class Visitor2 implements Visitor
{
    void visitA(A a, params);
    void visitB(B b, params);
}

Проблема

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

Решение

Для полной независимости посетители имеют отдельную от обслуживаемых структур иерархию. Структуры должны иметь некий интерфейс взаимодействия. При необходимости добавления новых операций необходимо создать новый класс ConcreteVisitor и поместить его в цепочку обхода обслуживаемых структур.

Рекомендации

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

  • в структуре присутствуют объекты разных классов с различными интерфейсами, и необходимо выполнить над ними операции, зависящие от конкретных классов.
  • если над обслуживаемой структурой надо выполнять самые различные, порой не связанные между собой операции. То есть они усложняют эту структуру.
  • часто добавляются новые операции над обслуживаемой структурой.
  • реализация double dispatch. Концептуально это нечто вроде {a; b} -> method(params), где реально вызываемый по стрелочке метод зависит как от типа a, так и от типа b. Так как большинство объектно-ориентированных языков программирования не поддерживает такое на уровне синтаксиса, для такого обычно применяется Visitor в виде a -> visit(b, params), который в свою очередь вызывает b -> visitA(a, params), что дает выбор и по типу a, и по типу b.

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

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

Недостатки

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

Ссылки

  • Robert C. Martin, Prentice Hall The Visitor Family of Design Patterns by Robert C. Martin - a rough chapter from The Principles, Patterns, and Practices of Agile Software Development. Архивировано из первоисточника 5 апреля 2012.
  • Паттерн Visitor (посетитель) — назначение, описание, особенности и реализация на С++.


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

© 2011–2023 krasorion.ru, Россия, Братск, ул. Ленинская 34, +7 (3953) 38-98-93