Visitor паттерн

В данной заметке я опишу паттерн проектирования под названием “Посетитель” или “Visitor”
Данный паттерн относится к группе Поведенических шаблонов.

Придумаем проблему

В основном, данный паттерн используют для обхода ограничения одиночной диспетчеризации (“single dispatch”), в языках с ранним связыванием.

Alice X by NFGPhoto (CC-2.0)
Создадим абстрактный класс/протокол Band, сделаем подкласс MurpleDeep, создадим класс Visitor с двумя методами – один для вывода в консоль любого наследника Band, второй для вывода любого MurpleDeep, главное чтобы имена (сигнатуры) у методов были одинаковые, а аргументы различались только классом. Через промежуточный метод printout с аргументом Band, создадим экземпляр Visitor и вызовем метод visit для MurpleDeep.
Далее код на Kotlin:

В выводе будет “This is Band class

Да как так то?!

Почему это происходит описано умными словами во многих статьях, в том числе и на русском, я же предлагаю вам представить как видит код компилятор, возможно все станет понятно сразу:

Решаем проблему

Для решения данной проблемы существует множество решений, далее рассмотрим решение с помощью паттерна Visitor.
В абстрактный класс/протокол добавляем метод accept с аргументом Visitor, внутри метода вызываем visitor.visit(this), после этого добавляем в класс MurpleDeep оверайд/имплементацию метода accept, решительно и спокойно нарушая DRY, снова пишем visitor.visit(this).
Итоговый код:

Источники

https://refactoring.guru/ru/design-patterns/visitor-double-dispatch

Исходный код

https://gitlab.com/demensdeum/patterns