设计模式之解释器模式

解释器模式

  1. 解释器模式结构图:

  2. 示例代码:

    // 抽象表达式角色
    public interface ArithmeticInterpreter {
        int interpret();
    }
    
    // 终结表达式角色
    public abstract class Interpreter implements ArithmeticInterpreter{
        protected ArithmeticInterpreter left;
        protected ArithmeticInterpreter right;
    
        public Interpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
            this.left = left;
            this.right = right;
        }
    }
    
    // 加法解释器
    public class AddInterpreter extends Interpreter{
        public AddInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return this.left.interpret() + this.right.interpret();
        }
    }
    
    // 减法解释器
    public class SubInterpreter extends Interpreter{
        public SubInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return this.left.interpret() - this.right.interpret();
        }
    }
    
    // 乘法解释器
    public class MultiInterpreter extends Interpreter{
        public MultiInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return this.left.interpret() * this.right.interpret();
        }
    }
    
    // 除法解释器
    public class DivInterpreter extends Interpreter{
        public DivInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right) {
            super(left, right);
        }
    
        @Override
        public int interpret() {
            return this.left.interpret() / this.right.interpret();
        }
    }
    
    // 数字表达式类
    public class NumInterpreter implements ArithmeticInterpreter{
        private int value;
    
        public NumInterpreter(int value) {
            this.value = value;
        }
    
        @Override
        public int interpret() {
            return value;
        }
    }
    
    // 计算器,没有考虑优先级,就是简单的从左到右的计算
    public class GPCalculator {
    
        private Stack<ArithmeticInterpreter> stack = new Stack<>();
    
        public GPCalculator(String expression){
            this.parse(expression);
        }
    
        private void parse(String expression) {
            String[] elements = expression.split(" ");
            ArithmeticInterpreter left;
            ArithmeticInterpreter right;
    
            for (int i = 0; i < elements.length; i++) {
                String operator = elements[i];
                if (OperatorUtil.ifOperator(operator)){
                    left = this.stack.pop();
                    right = new NumInterpreter(Integer.valueOf(elements[++i]));
                    System.out.println("出栈" + left.interpret() + "和" + right.interpret());
                    this.stack.push(OperatorUtil.getInterpreter(left,right,operator));
                    System.out.println("应用运算符:" + operator);
                }else {
                    NumInterpreter numInterpreter = new NumInterpreter(Integer.valueOf(elements[i]));
                    this.stack.push(numInterpreter);
                    System.out.println("入栈" + numInterpreter.interpret());
                }
            }
        }
    
        public int calculate(){
            return this.stack.pop().interpret();
        }
    }
    
    // 工具类
    public class OperatorUtil {
        public static boolean ifOperator(String operator) {
    
            return (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/"));
        }
    
        public static ArithmeticInterpreter getInterpreter(ArithmeticInterpreter left, ArithmeticInterpreter right, String operator) {
            if (operator.equals("+")){
                return new AddInterpreter(left,right);
            }else if (operator.equals("-")){
                return new SubInterpreter(left, right);
            }else if (operator.equals("*")){
                return new MultiInterpreter(left, right);
            }else if (operator.equals("/")){
                return new DivInterpreter(left, right);
            }
            return null;
        }
    }
    
    // 测试类
    public class InterpreterTest {
    
        public static void main(String[] args) {
            System.out.println("result: " + new GPCalculator("10 + 30").calculate());
            System.out.println("result: " + new GPCalculator("10 + 30 - 20").calculate());
            System.out.println("result: " + new GPCalculator("100 * 2 + 30").calculate());
        }
    }
    
  3. 总结:

    优点:解偶,增加了新的解释表达式的方式;

    缺点:每个语法都要产生一个非终结符表达式,增加了系统的维护难度,解释器采用递归调用的方法,当完整表达式层级较深时,解释效率下降,且出错时调试困难.

posted @ 2021-04-29 00:46  justKen  阅读(43)  评论(0编辑  收藏  举报