zoukankan      html  css  js  c++  java
  • 设计模式学习总结(十六)--解释器模式

    定义

    解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    角色

    • AbstractExpression: 抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。

    • TerminalExpression: 终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。

    • NonterminalExpression: 非终结符表达式。为文法中的非终结符相关的解释操作。

    • Context: 环境类。包含解释器之外的一些全局信息。

    • Client: 客户类。

    优缺点

    优点:

    • 可扩展性比较好,灵活。

    • 增加了新的解释表达式的方式。

    • 易于实现文法。

    缺点:

    • 执行效率比较低,可利用场景比较少。

    • 对于复杂的文法比较难维护。

    实例(以乘除公式为例)

    定义节点接口:

    /**
     * 节点
     */
    public interface Node {
    
        /**
         * 解释
         *
         * @return
         */
        int interpret();
    }
    

    节点具体实现类:

    /**
     * 值节点
     */
    public class ValueNode implements Node{
    
        private int value;
    
        public ValueNode(int value){
            this.value = value;
        }
    
        @Override
        public int interpret() {
            return this.value;
        }
    }
    
    
    /**
     * 符号节点抽象类
     */
    public abstract class SymbolNode implements Node {
    
        protected Node left;
        protected Node right;
    
        public SymbolNode(Node left, Node right) {
            this.left = left;
            this.right = right;
        }
    }
    
    /**
     * 乘法
     */
    public class MultiplyNode extends SymbolNode{
    
        public MultiplyNode(Node left, Node right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return left.interpret() * right.interpret();
        }
    }
    
    /**
     * 除法
     */
    public class DivisionNode extends SymbolNode {
        public DivisionNode(Node left, Node right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return left.interpret() / right.interpret();
        }
    }
    
    

    计算器:

    public class Calculator {
    
        private Node node;
    
        public void build(String statement) {
            Node left,right;
            Stack stack = new Stack();
    
            String[] statementArr = statement.split(" ");
    
            for (int i = 0; i < statementArr.length; i++) {
                if (statementArr[i].equalsIgnoreCase("*")) {
                    left = (Node) stack.pop();
                    int val = Integer.parseInt(statementArr[++i]);
                    right = new ValueNode(val);
                    stack.push(new MultiplyNode(left, right));
                } else if (statementArr[i].equalsIgnoreCase("/")) {
                    left = (Node) stack.pop();
                    int val = Integer.parseInt(statementArr[++i]);
                    right = new ValueNode(val);
                    stack.push(new DivisionNode(left, right));
                } else {
                    stack.push(new ValueNode(Integer.parseInt(statementArr[i])));
                }
            }
            this.node = (Node) stack.pop();
        }
    
        public int compute() {
            return node.interpret();
        }
    }
    

    测试:

    public static void main(String[] args) {
        String statement = "3 * 2 * 4 / 6";
    
        Calculator calculator = new Calculator();
    
        calculator.build(statement);
    
        int result = calculator.compute();
    
        System.out.println(statement + " = " + result);
    }
    

    控制台输出:

    3 * 2 * 4 / 6 = 4
    
  • 相关阅读:
    PIL.Image 与 base64互转
    python pytorch ssd网络
    mysql 的左连接、又连接、内连接详细介绍
    base64图片数据类型转numpy的ndarray矩阵类型数据
    kettle学习资料
    kettle 连接 mysql8.0 报错的解决办法 org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while trying to connect to the database Error connecting to database: (using class org.gjt.mm.mysql.
    python pandas 自动生成批量测试数据插入数据库 mysql
    finereport点击图表钻取到明细表包括参数传递
    finereport连接mysql8.0的解决办法
    kettle7.0 Windows10 mysql8.0 连接mysql驱动报错,问题解决
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11582652.html
Copyright © 2011-2022 走看看