Посетитель (Visitor) :: Cетевой уголок Majestio

Посетитель (Visitor)


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

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

Подробнее на 👉 refactoring.guru

UML-диаграмма

Пример реализации

#include <iostream>
#include <string>

// Объявление классов элементов

class ConcreteElement1;
class ConcreteElement2;

// Интерфейс посетителя

class Visitor {
 public:
  virtual void visit(ConcreteElement1& element) = 0;
  virtual void visit(ConcreteElement2& element) = 0;
};

// Интерфейс элемента

class Element {
 public:
  virtual void accept(Visitor& visitor) = 0;
};

// Конкретный элемент 1

class ConcreteElement1 : public Element {
 public:
  void accept(Visitor& visitor) override { visitor.visit(*this); }
  std::string operation1() { return "Операция 1 на ConcreteElement1"; }
};

// Конкретный элемент 2

class ConcreteElement2 : public Element {
 public:
  void accept(Visitor& visitor) override { visitor.visit(*this); }
  std::string operation2() { return "Операция 2 на ConcreteElement2"; }
};

// Конкретный посетитель

class ConcreteVisitor : public Visitor {
 public:
  void visit(ConcreteElement1& element) override {
    std::cout << element.operation1() << std::endl;
  }

  void visit(ConcreteElement2& element) override {
    std::cout << element.operation2() << std::endl;
  }
};

// Клиентский код

int main() {
  ConcreteElement1 element1;
  ConcreteElement2 element2;
  ConcreteVisitor visitor;
  element1.accept(visitor);
  element2.accept(visitor);
  return 0;
}
Будет напечатано:
Операция 1 на ConcreteElement1
Операция 2 на ConcreteElement2
// Интерфейс элемента

abstract class Element {
  void accept(Visitor visitor);
}

// Конкретный элемент 1

class ConcreteElement1 implements Element {
  @override
  void accept(Visitor visitor) {
    visitor.visitConcreteElement1(this);
  }

  String operation1() {
    return 'Операция 1 на ConcreteElement1';
  }
}

// Конкретный элемент 2

class ConcreteElement2 implements Element {
  @override
  void accept(Visitor visitor) {
    visitor.visitConcreteElement2(this);
  }

  String operation2() {
    return 'Операция 2 на ConcreteElement2';
  }
}

// Интерфейс посетителя

abstract class Visitor {
  void visitConcreteElement1(ConcreteElement1 element);
  void visitConcreteElement2(ConcreteElement2 element);
}

// Конкретный посетитель

class ConcreteVisitor implements Visitor {
  @override
  void visitConcreteElement1(ConcreteElement1 element) {
    print(element.operation1());
  }

  @override
  void visitConcreteElement2(ConcreteElement2 element) {
    print(element.operation2());
  }
}

// Клиентский код

void main() {
  var element1 = ConcreteElement1();
  var element2 = ConcreteElement2();

  var visitor = ConcreteVisitor();

  element1.accept(visitor);
  element2.accept(visitor);
}
Будет напечатано:
Операция 1 на ConcreteElement1
Операция 2 на ConcreteElement2
Рейтинг: 0/5 - 0 голосов