Существует много разговоров о развязывании алгоритмов из классов. Но одно остается в стороне, а не объяснено.
Они используют посетителя таким образом
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" для техника."