В данной заметке я опишу паттерн проектирования под названием “Посетитель” или “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