java - 解释器的访问者模式 - 基于实例类型调用方法

标签 java

下面的代码显然由于类型不兼容而无法编译。然而,我正在尝试做类似的事情。为了让这个工作据我所知,我必须采用父类(super class)并检查它是什么类型,并使用 switch case 或讨厌的 if else 设置。我可以在这里利用多态性,将访问方法放在 ASTNode 中,并在每个子类中重写它,但是,当我想确保它保留在 Interpreter 类中时,这就是将逻辑放入 ASTNode 类中。

public class Test {

    private class ASTNode{

    }
    private class ExprNode extends ASTNode{

    }
    private class VarNode extends ASTNode{

    }
    private class Interpreter{

        public Interpreter(ASTNode node){
            this.visit(node);
        }

        public void visit(ExprNode node){

        }
        public void visit(VarNode node){

        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        ASTNode node = new ExprNode();
        Interpreter interpreter =  new Interpreter(node);
    }
}

我正在构建一个解释器,并且正在使用解释器的访问者模式。每种类型的节点都有一个访问方法。在我正在使用 python 编写的示例中,他们使用 getattr 方法,该方法根据子类将调用分派(dispatch)给正确的方法。我不知道 Java 有类似的东西。

最后,如果我要在这里使用多态性,我将为 ASTNode 类中的解释器和语义分析器定义不同的访问方法。我喜欢在解释器类中拥有解释器逻辑的想法,但我不想有一个基于子类类型的巨大开关案例。

这里有什么想法吗?也许我缺少一种简单的技术。

最佳答案

访问者模式的要点是通过处理单个子类上的访问者调用来用多态性替换“巨大的开关”。这并不意味着逻辑包含在子类中,而是在访问者类上定义。在您的示例中,情况如下:

interface NodeVisitor {
    void visit(ExprNode node);
    void visit(VarNode node);
}

class Interpreter implements NodeVisitor {
    @Override
    public void visit(ExprNode node) {
        // custom logic here
    }

    @Override
    public void visit(VarNode node) {
        // custom logic here
    }
}

private class ASTNode {
    public abstract void accept(NodeVisitor visitor);
}

private class ExprNode extends ASTNode {
    @Override
    public void accept(NodeVisitor visitor) {
        visitor.visit(this);
    }
}

private class VarNode extends ASTNode {
    @Override
    public void accept(NodeVisitor visitor) {
        visitor.visit(this);
    }
}

public static void main(String[] args) {
    ASTNode node = new ExprNode();
    node.accept(new Interpreter());
}

关于java - 解释器的访问者模式 - 基于实例类型调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40601211/

相关文章:

java - 在安卓上使用服务加载器

java - android reshape 所有资源文件字符串

Java Soap 请求 - 读取 soap 响应

java - 我可以使用 JMX 远程检测 Java 代码吗?

java - 标准、独立子查询、分组依据和拥有更多

java - (Android Java Sqlite)由于IP地址导致连接数据库失败时如何提示toast

java - HttpURLConnection 不提交 POST 数据 (Android)

java - OSX 10.7 (Lion) 上的 Lejos

java - 如何使用 GSON 反序列化不同对象的数组

java - 使用 equals 比较字符