【发布时间】:2011-07-20 12:54:12
【问题描述】:
【问题讨论】:
-
你不明白的地方能不能具体点?
-
恕我直言,您应该考虑在运行时而不是编译时将分派作为函数重载。
标签: java design-patterns visitor-pattern double-dispatch
【问题讨论】:
标签: java design-patterns visitor-pattern double-dispatch
单发
假设Node是一个接口类,两个子类是接口的具体实现。
如果您在节点实例上调用GenerateCode() 方法,实际执行的操作取决于节点的类型。它可以是VariableRefNode 或AssignmentNode 中的方法。拨打PrettyPrint()也是一样。因此,实际执行的操作取决于您正在调用的方法的名称和节点的类型。
双发
这次Node 允许您将NodeVisitor 类型的参数传递给它的名为Accept 的方法。在您的程序中,如果您在节点实例上调用Accept,现在执行的实际操作取决于节点的类型(VariableRefNode 或AssignmentNode)AND 您传递给Accept 的访问者实例的类型(TypeCheckingVisitor 或CodeGeneratingVisitor)。
【讨论】:
元素对象的accept 方法接收一个访问者对象,并在访问者对象上调用visit 方法。由于访问者对象有多个visit 方法,因此根据元素类型调用适当的visit 方法。这里我们有两个调用(double dispatch)来指定元素的元素和正确的操作(基于它的类型)。
【讨论】:
嗯,这是那篇文章的相关引述:
Visitor 实现了“双重调度”。 OO 消息通常表现为“单次调度”——执行的操作取决于:请求的名称和接收者的类型。在“双重调度”中,执行的操作取决于:请求的名称,以及两个接收者的类型(访问者的类型和它访问的元素的类型)。
这实质上意味着不同的访问者可以访问相同的类型,并且同一访问者可以访问不同的类型。使用访问者模式执行的命名操作的效果可能取决于访问者和访问者(双重调度)。
【讨论】:
显示双重调度的示例代码:
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
【讨论】: