В чем смысл метода accept () в шаблоне посетителя?

Много говорят об отделении алгоритмов от классов . Но одна вещь остается в стороне и не объясняется.

Они используют посетителя, как этот

abstract class Expr {
  public  T accept(Visitor 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), Visitor просит элемент вызвать его метод посещения. Это противоречит заявленному представлению о классовой неосведомленности о посетителях.

PS1 Пожалуйста, объясните своими словами или укажите точное объяснение. Потому что два ответа, которые я получил, относятся к чему-то общему и неопределенному.

PS2 Мое предположение: поскольку getLeft () возвращает основное выражение , вызов visit (getLeft ()) приведет к visit (Expression ) , тогда как getLeft () вызов visit (this) приведет к другому, более подходящему вызову посещения. Итак, accept () выполняет преобразование типа (также известное как приведение типов).

PS3 Сопоставление с шаблоном Scala = шаблон посетителя на стероиде показывает, насколько проще шаблон посетителя без метода accept. Википедия добавляет к этому утверждению : путем ссылки на статью, показывающую, что «методы accept () не нужны, когда отражение доступно; вводит термин« обходной путь »для этой техники».

76
задан jaco0646 2 August 2016 в 14:06
поделиться