20

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

请参考链接 访客模式

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

4

4 回答 4

55

单次派送

单次派送

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

如果您GenerateCode()在节点实例上调用方法,则执行的实际操作取决于节点的类型。它可以是VariableRefNode或中的方法AssignmentNode。如果你打电话也是一样的PrettyPrint()。因此,实际执行的操作取决于您正在调用的方法的名称和节点的类型

双重派送

节点 访客

这一次Node允许你将一个类型的参数传递NodeVisitor给它的名为Accept. 在您的程序中,如果您调用Accept节点实例,现在执行的实际操作取决于节点的类型VariableRefNodeAssignmentNode您传入的访问者实例的类型AcceptTypeCheckingVisitorCodeGeneratingVisitor)。

于 2012-10-03T06:18:07.770 回答
21

元素对象的accept方法接收一个访问者对象并调用访问者对象的visit方法。由于访问者对象有多种visit方法,因此根据元素类型visit调用适当的方法。这里我们有两个调用(double dispatch)来指定元素和元素的正确操作(基于它的类型)。

于 2011-07-20T13:20:30.483 回答
11

好吧,这是那篇文章的相关引述:

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

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

于 2011-07-20T13:17:20.960 回答
3

显示双重调度的示例代码:

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
于 2019-02-06T16:49:37.670 回答