[Design Mode] 21, Interpreter Mode

(21) Interpreter Mode

The Interpreter Pattern, given a language, defines its grammatical representation, and defines an interpreter that uses that identity to interpret sentences in the language. If a particular type of problem occurs frequently enough, it may be worth expressing the instances of the problem as sentences in a simple language. This makes it possible to build an interpreter that solves the problem by interpreting these sentences.

1. Design principles of the interpreter pattern

1, abstract expression (IExpression):, define the abstract method interpret;

2, Terminal Expression (TerminalExpression): realizes the interpretation operation related to the terminal symbol in the grammar;

3. Nonterminal Expression (NonterminalExpression): Realize the interpretation operations related to nonterminals in the grammar;

4. Context: global information outside the interpreter.

2. Simple example

Use interpreter mode to encapsulate addition, subtraction, multiplication and division operations.

public interface IMathInterpreter {
    
    
    /**
     * 顶级方法
     * @return
     */
    int interpreter();
}
public class NumInterpreter implements IMathInterpreter {
    
    
    public int value;

    public NumInterpreter(int value) {
    
    
        this.value = value;
    }

    @Override
    public int interpreter() {
    
    
        return this.value;
    }
}
public class AddInterpreter extends Interpreter {
    
    

    /**
     * 子类继承父类,可以重写父类方法,必须重写构造方法。
     * @param left
     * @param right
     */
    public AddInterpreter(IMathInterpreter left, IMathInterpreter right) {
    
    
        super(left, right);
    }


    @Override
    public int interpreter() {
    
    
        return this.left.interpreter()+this.right.interpreter();
    }
}
public class SubInterpreter extends Interpreter {
    
    

    public SubInterpreter(IMathInterpreter left, IMathInterpreter right) {
    
    
        super(left, right);
    }

    @Override
    public int interpreter() {
    
    
        return this.left.interpreter()-this.right.interpreter();
    }
}
public class MultiInterpreter extends Interpreter {
    
    

    public MultiInterpreter(IMathInterpreter left, IMathInterpreter right) {
    
    
        super(left, right);
    }

    @Override
    public int interpreter() {
    
    
        return this.left.interpreter()*this.right.interpreter();
    }
}
public class DivInterpreter extends Interpreter {
    
    
    public DivInterpreter(IMathInterpreter left, IMathInterpreter right) {
    
    
        super(left, right);
    }

    @Override
    public int interpreter() {
    
    
        return this.left.interpreter()/this.right.interpreter();
    }
}
public class Calculator {
    
    
    private Stack<IMathInterpreter> stack = new Stack<>();

    public Calculator(String expression){
    
    
        this.parse(expression);
    }

    /**
     * 此处仅考虑简单计算,从左至右直接算
     * @param expression
     */
    public void parse(String expression){
    
    
        String[] ele = expression.split(" ");
        IMathInterpreter left,right;

        for(int i=0;i<ele.length;i++){
    
    
            String operator = ele[i];
            if(OperatorUtils.ifOperator(operator)){
    
    
//                是操作符,将前一个数字弹出
                left = stack.pop();
                right = new NumInterpreter(Integer.valueOf(ele[++i]));
                System.out.println("出栈:"+left.interpreter()+"和"+right.interpreter());
//                将计算结果压入栈中
//                通过传递待计算项,由解释器复制解释
                this.stack.push(OperatorUtils.getInterpreter(left,right,operator));
                System.out.println("运算符:"+operator);
            }else {
    
    
                NumInterpreter numInterpreter = new NumInterpreter(Integer.valueOf(ele[i]));
                this.stack.push(numInterpreter);
                System.out.println("入栈:"+numInterpreter.interpreter());
            }
        }
    }

    public int calculate(){
    
    
//       计算时直接弹出结果即可
        return this.stack.pop().interpreter();
    }
}
public class OperatorUtils {
    
    
    public static boolean ifOperator(String symbol){
    
    
        return (symbol.equals("+")||symbol.equals("-")||symbol.equals("*")||symbol.equals("/"));
    }
    public static Interpreter getInterpreter(IMathInterpreter left, IMathInterpreter right,String symbol){
    
    
        if("+".equals(symbol)){
    
    
            return new AddInterpreter(left, right);
        }else if("-".equals(symbol)){
    
    
            return new SubInterpreter(left, right);
        }else if ("*".equals(symbol)){
    
    
            return new MultiInterpreter(left, right);
        }else if ("/".equals(symbol)){
    
    
            return new DivInterpreter(left, right);
        }
        return null;
    }
}
public class Client {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(new Calculator("3 + 4").calculate());
    }
}

image-20210330121616301

3. Evaluation of Interpreter Mode

Interpreter mode increases system complexity with the complexity of the grammar. Good extensibility, easy to implement simple grammar.

Guess you like

Origin blog.csdn.net/qq_40589204/article/details/119914758