zoukankan      html  css  js  c++  java
  • 解释器模式

    一、定义

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

    简单理解:为了解释一种语言,而为语言创建的解释器。

    C#代码,Java代码的编译器就相当于一个解释器。

    类型: 行为型

    二、适用场景

    1、某个特定类型问题发生频率足够高

    如程序中有很多日志,对日志进行解析就是解析器。日常使用比较少(低频)。

    三、解释器-优点

    语法由很多类表示,容易改变及扩展此“语言”

    四、解释器模式-缺点

    1、当语法规则数目太多时,增加了系统的复杂度

    规则太多,每个规则都要写一个类。

    五、解释器模式-相关设计模式

    1、解释器模式和适配器模式

    适配器模式是不需要预先知道要适配的规则

    解析器模式把规则写好,根据规则执行解释。

    六、Coding

    1、Interpreter 接口

    public interface Interpreter {
        //解释
        int interpret();
    }
    

      

    2、 加法解释器 AddInterprete

    /**
     * 加法解释器
     */
    public class AddInterpreter  implements  Interpreter{
    
        private Interpreter firstExpression, secondExpression;
    
        public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
    
        @Override
        public int interpret() {
            //第一个表达式的解释+第二个表达式的解释
            return firstExpression.interpret() + secondExpression.interpret();
        }
    
        @Override
        public String toString() {
            return "+";
        }
    }
    

      

    3、 乘法解释器 MultiInterpreter

    /**
     * 乘法解释器
     */
    public class MultiInterpreter implements  Interpreter{
    
        private Interpreter firstExpression, secondExpression;
    
        public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
            this.firstExpression = firstExpression;
            this.secondExpression = secondExpression;
        }
    
        @Override
        public int interpret() {
            //第一个表达式的解释*第二个表达式的解释
            return firstExpression.interpret() * secondExpression.interpret();
        }
    
        @Override
        public String toString() {
            return "*";
        }
    }
    

      

    4、数字解释器NumberInterprete

    /**
     * 数字解释器
     */
    public class NumberInterpreter implements  Interpreter{
    
        private int number;
    
        public NumberInterpreter(int number) {
            this.number = number;
        }
    
        public NumberInterpreter(String number) {
            this.number = Integer.parseInt(number);
        }
    
        @Override
        public int interpret() {
            return this.number;
        }
    
    
    }
    

      

    5、工具类OperatorUtil 

    public class OperatorUtil {
    
        /**
         * 是否是操作符
         * @param symbol
         * @return
         */
        public  static  boolean isOperator(String symbol){
            return  ( "+".equals(symbol) || "*".equals(symbol));
        }
    
        public static  Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol){
            if("+".equals(symbol)){
                return  new AddInterpreter(firstExpression, secondExpression);
            }else if("*".equals(symbol)){
                return  new MultiInterpreter(firstExpression, secondExpression);
            }
            return  null;
        }
    }
    

      

    6、LarryExpressionParser 类

    public class LarryExpressionParser {
        private Stack<Interpreter> stack = new Stack<>();
    
        public  int parse(String str){
            String[] strInemArray = str.split(" ");
            for(String item : strInemArray){
                if(!OperatorUtil.isOperator(item)){
                    Interpreter numberExpression = new NumberInterpreter(item);
                    stack.push(numberExpression);
                    System.out.println(String.format("入栈:%d", numberExpression.interpret()));
                }else {
                    //是运算符号可以计算
                    Interpreter firstExpression = stack.pop();
                    Interpreter secondExpression = stack.pop();
                    System.out.println(String.format("出栈: %d 和 %d", firstExpression.interpret(), secondExpression.interpret()));
                    Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, item);
                    System.out.println(String.format("应用运算符: %s", operator));
                    int result = operator.interpret();
                    NumberInterpreter resultExpress = new NumberInterpreter(result);
                    stack.push(resultExpress);
                    System.out.println(String.format("阶段结果入栈: %d", resultExpress.interpret()));
                }
    
            }
            int result = stack.pop().interpret();
            return  result;
    
        }
    }
    

      

    7、测试类

    public class Test {
    
        public static void main(String[] args) {
            String input = "6 100 11 + *"; //(100+11)*6=666
            LarryExpressionParser larryExpressionParser = new LarryExpressionParser();
            int result = larryExpressionParser.parse(input);
            System.out.println("解释器计算结果:" +  result);
        }
    }
    

      

    8、测试结果

     9、UML图

    七、在源码中的应用

    1、Pattern正则

    2、Spring EL表达式

    import org.springframework.expression.Expression;
    import org.springframework.expression.ExpressionParser;
    import org.springframework.expression.spel.standard.SpelExpressionParser;
    
    
    public class SpringTest {
        public static void main(String[] args) {
            ExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression("100 * 3 + 500 * 2 + 6 * 5");
            int result = (Integer)expression.getValue();
            System.out.println(result);
        }
    }
    

      结果如下图

  • 相关阅读:
    Unity3D鼠标点击处
    Unity3D静态AI自动寻路
    Unity3D 雷达检测器
    Unity3D重新加载光线变暗问题
    Unity3D切换场景不销毁物体
    软件&环境&网页
    2020软件工程作业05
    2020软件工程作业04
    利用Java输入输出流更改文件中指定的内容
    2020软件工程作业03
  • 原文地址:https://www.cnblogs.com/linlf03/p/10453004.html
Copyright © 2011-2022 走看看