双重调度如何在访客模式中工作?

时间:2011-07-20 12:54:12

标签: java design-patterns visitor-pattern double-dispatch

我正在调查与访问者模式相关的其他问题,但无法理解访问者模式中双重调度的实现。

请参阅链接 Visitor Pattern

双重调度如何在访客模式中工作?

4 个答案:

答案 0 :(得分:37)

<强>单调度

Single dispatch

假设Node是一个接口类,两个子类是接口的具体实现。

如果在节点实例上调用GenerateCode()方法,则执行的实际操作取决于节点的类型。它可以是VariableRefNodeAssignmentNode中的方法。如果您致电PrettyPrint(),情况也是如此。因此,执行的实际操作取决于您正在调用的方法的名称以及节点的类型

<强>双调度

Nodes Visitors

这次Node允许您将NodeVisitor类型的参数传递给名为Accept的方法。在程序中,如果在节点实例上调用Accept,则现在执行的实际操作取决于节点的类型VariableRefNodeAssignmentNode)< strong> AND 您传入AcceptTypeCheckingVisitorCodeGeneratingVisitor)的访问者实例的类型。

答案 1 :(得分:20)

元素对象的accept方法接收访问者对象,并在访问者对象上调用visit方法。由于访问者对象具有多个visit方法,因此基于元素类型调用适当的visit方法。这里我们有两个调用(双调度),为元素指定元素和右操作(基于其类型)。

答案 2 :(得分:6)

嗯,这是该文章的相关引用:

  

访客实施“双重调度”。 OO消息通常表现为“单一调度” - 执行的操作取决于:请求的名称和接收者的类型。在“双重调度”中,执行的操作取决于:请求的名称,以及TWO接收者的类型(访问者的类型及其访问的元素的类型)。

这实质上意味着不同的访问者可以访问相同类型,同一访问者可以访问不同类型。使用访客模式执行的命名操作的效果可能取决于访问者访问者(双重调度)。

答案 3 :(得分:0)

示例代码,显示了双重调度:

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