Я изучал другие вопросы, связанные с шаблоном посетителя, но не мог понять реализацию двойной отправки в шаблоне посетителя.
Пожалуйста, обратитесь к ссылке Шаблон посетителя
Как работает двойная диспетчеризация в шаблоне посетителя?
Я изучал другие вопросы, связанные с шаблоном посетителя, но не мог понять реализацию двойной отправки в шаблоне посетителя.
Пожалуйста, обратитесь к ссылке Шаблон посетителя
Как работает двойная диспетчеризация в шаблоне посетителя?
Метод object accept
принимает объект-посетитель и вызывает метод visit
на объекте-посетителе. Поскольку объект-посетитель имеет несколько методов visit
, на основе типа элемента вызывается соответствующий метод visit
. Здесь у нас есть два вызова (двойная отправка), которые определяют элемент и правильную операцию для элемента (в зависимости от его типа).
Single-диспетчерская
Предположим, что Node является классом интерфейса, а два подкласса - это конкретные реализации интерфейса.
Если вы вызываете метод GenerateCode()
на экземпляр Node, фактическая операция, выполняемая в процессе выполнения, зависит от типа node. Это может быть метод либо в VariableRefNode
, либо AssignmentNode
. То же самое, если вы вызываете PrettyPrint()
. Таким образом, фактическая операция, выполняемая, зависит от имени метода, который вы вызываете, и типа node.
Дважды диспетчерская
На этот раз Node
позволяет передать параметр типа NodeVisitor
его методу Accept
. В вашей программе, если вы вызываете Accept
в экземпляре Node, фактическая операция, выполняемая сейчас, зависит от типа Node (VariableRefNode
или AssignmentNode
) И типа экземпляра посетителя, который вы передали в Accept
(TypeCheckingVisitor
или CodeGeneratingVisitor
).
Ну, вот соответствующая цитата из этой статьи:
Посетитель реализует "двойную отправку". Сообщения OO обычно демонстрируют "единую отправку" - выполняемая операция зависит от: имени запроса и типа получателя. В "двойной отправке" выполняемая операция зависит от: имени запроса и типа TWO-приемников (типа посетителя и типа элемента, который он посещает).
Это по существу означает, что разные посетители могут посещать один и тот же тип, и разные посетители могут посещать один и тот же посетитель. Эффект именованной операции, выполняемой с использованием шаблона посетителя, может зависеть от посетителя и посещенной (двойной отправки).
Пример кода, который показывает двойную отправку:
import java.util.Arrays;
import java.util.List;
class Client {
public static void main(String[] args) {
List<Node> nodes = Arrays.asList(new NodeA(), new NodeB());
List<NodeVisitor> visitors = Arrays.asList(new NodeVisitor1(), new NodeVisitor2());
for (Node node : nodes) {
for (NodeVisitor visitor : visitors) {
node.accept(visitor);
}
}
}
}
interface Node {
void accept(NodeVisitor visitor);
}
interface NodeVisitor {
void visit(Node node);
}
class NodeA implements Node {
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return "Node A";
}
}
class NodeB implements Node {
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
@Override
public String toString() {
return "Node B";
}
}
class NodeVisitor1 implements NodeVisitor {
@Override
public void visit(Node node) {
System.out.println("Node visitor 1, node " + node);
}
}
class NodeVisitor2 implements NodeVisitor {
@Override
public void visit(Node node) {
System.out.println("Node visitor 2, node " + node);
}
}
Выход:
Node visitor 1, node Node A
Node visitor 2, node Node A
Node visitor 1, node Node B
Node visitor 2, node Node B