Java 在访客模式中,双重分派是如何工作的?
我正在研究与访问者模式相关的其他问题,但无法理解访问者模式中双重分派的实现 请参考链接Java 在访客模式中,双重分派是如何工作的?,java,design-patterns,visitor-pattern,double-dispatch,Java,Design Patterns,Visitor Pattern,Double Dispatch,我正在研究与访问者模式相关的其他问题,但无法理解访问者模式中双重分派的实现 请参考链接 在访客模式中,双重分派是如何工作的?好吧,下面是那篇文章的相关引用: 访客执行“双重分派”。OO消息通常表现为“单一分派”——执行的操作取决于:请求的名称和接收方的类型。在“双重分派”中,执行的操作取决于:请求的名称和两个接收者的类型(访问者的类型和它访问的元素的类型) 这本质上意味着不同的访问者可以访问同一类型,同一访问者可以访问不同类型。使用访问者模式执行的命名操作的效果可能取决于访问者和已访问的(双重
在访客模式中,双重分派是如何工作的?好吧,下面是那篇文章的相关引用: 访客执行“双重分派”。OO消息通常表现为“单一分派”——执行的操作取决于:请求的名称和接收方的类型。在“双重分派”中,执行的操作取决于:请求的名称和两个接收者的类型(访问者的类型和它访问的元素的类型)
这本质上意味着不同的访问者可以访问同一类型,同一访问者可以访问不同类型。使用访问者模式执行的命名操作的效果可能取决于访问者和已访问的(双重分派)。元素对象的
accept
方法接收访问者对象,并对访问者对象调用visit
方法。由于访问者对象有几个visit
方法,因此根据元素类型调用相应的visit
方法。这里我们有两个调用(双重分派),用于指定元素和元素的正确操作(基于其类型) 单一分派
假设Node是一个接口类,两个子类是接口的具体实现
如果对节点实例调用GenerateCode()
方法,实际执行的操作取决于节点的类型。它可以是VariableRefNode
或AssignmentNode
中的方法。如果调用PrettyPrint()
,也是一样的。因此,实际执行的操作取决于所调用方法的名称和节点的类型
双重分派
这一次,
节点
允许您将类型为NodeVisitor
的参数传递给其名为Accept
的方法。在程序中,如果对节点实例调用Accept
,现在执行的实际操作取决于节点的类型(VariableRefNode
或AssignmentNode
)和Accept
(TypeCheckingVisitor
或CodeGeneratingVisitor
)。一个示例代码,显示双重分派:
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