Добавляет новые операции к иерархии классов без изменения самих классов. Двойная диспетчеризация: элемент принимает посетителя, посетитель вызывает метод для конкретного типа элемента.
interface Visitor { function visitA(ElementA $e): void; function visitB(ElementB $e): void; }
interface Element { function accept(Visitor $v): void; }
class ElementA implements Element {
public function accept(Visitor $v): void { $v->visitA($this); }
}Применение: экспорт в разные форматы (JSON, XML), подсчет статистики по AST. Минус: добавление нового типа элемента требует менять всех посетителей.