Много говорят об отделении алгоритмов от классов . Но одна вещь остается в стороне и не объясняется.
Они используют посетителя, как этот
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 ()
не нужны, когда отражение доступно; вводит термин« обходной путь »для этой техники».