Существует много разговоров о развязывании алгоритмов из классов. Но одно остается в стороне, а не объяснено.
Они используют посетителя таким образом
abstract class Expr {
  public <T> T accept(Visitor<T> visitor) {visitor.visit(this);}
}
class ExprVisitor extends Visitor{
  public Integer visit(Num num) {
    return num.value;
  }
  public Integer visit(Sum sum) {
    return sum.getLeft().accept(this) + sum.getRight().accept(this);
  }
  public Integer visit(Prod prod) {
    return prod.getLeft().accept(this) * prod.getRight().accept(this);
  }
Вместо прямого вызова функции visit (element), посетитель запрашивает элемент для вызова метода посещения. Это противоречит заявленной идее классовой неосведомленности о посетителях.
PS1 Пожалуйста, объясните своими словами или укажите точное объяснение. Потому что два ответа, которые я получил, касаются чего-то общего и неопределенного.
PS2 Мое предположение: поскольку getLeft() возвращает базовый Expression, вызов visit(getLeft()) приведет к visit(Expression), тогда как getLeft() вызов visit(this) приведет к другому, более подходящему вызову посещения. Таким образом, accept() выполняет преобразование типа (aka casting).
PS3 Scala Pattern Matching = Visitor Pattern on Steroid показывает, насколько проще шаблон посетителя без метода accept. Wikipedia добавляет к этому утверждению: путем ссылки на документ, показывающий, что методы accept() не нужны, когда доступно отражение, вводит термин "Walkabout" для техника."