Шаблон посетителя, как (первый?) Описан в «Шаблонах проектирования» Эриха Гамма и др. и др. не обязательно включает обход структуры данных в методе accept. Хотя это очень удобная комбинация, в конце главы «Пример кода» в книге приведен явный пример для внешней итерации.
Таким образом, как уже говорили другие, обход в глубину, реализованный вне метода accept, все еще может реализовать шаблон посетителя. Тогда возникает вопрос, в чем разница между вызовом element.accept (посетитель), который, в свою очередь, напрямую вызывает visitor.visitElement (me) по сравнению с прямым вызовом visitor.visitElement (элемент)?
Я вижу только две причины, по которым можно это сделать:
Вы не можете или не хотите узнать конкретный класс элемента, и просто тупо вызывая element.accept (посетитель), сам элемент должен решить, является ли visitor.visitElement или, например, visitor.visitAnotherElement - правильная операция для вызова.
Некоторые элементы являются композиционными и не имеют внешнего доступа к содержащимся внутренним элементам, а операции посетителя определены для внутренних элементов. Таким образом, метод accept будет зацикливаться на внутренних элементах и будет вызывать visitor.visitInnerElement (innerElement). И так как вы не получаете внутренние элементы извне, вы также не можете вызвать visitor.visitInnerElememt (innerElement) извне.
В итоге: если у вас есть хорошо инкапсулированный алгоритм обхода, в котором вы можете передать класс, похожий на «Visitor», и который может отправлять соответствующие методы посещения в зависимости от типа объекта, обнаруженного во время обхода, вы делаете не надо беспокоиться о приеме-методах. Вы по-прежнему сможете добавлять новые операции, просто добавляя новые реализации Visitor и не затрагивая ни структуру данных, ни алгоритм обхода. Должно ли это все еще называться Шаблон посетителя - довольно академическая дискуссия.
Я думаю, что в большинстве случаев использование метода accept имеет смысл только в том случае, если реализация метода accept также включает обход.