[Modo de diseño] 21, Modo de intérprete

(21) Modo Intérprete

El patrón de intérprete, dado un idioma, define su representación gramatical y define un intérprete que usa esa identidad para interpretar oraciones en el idioma. Si un tipo particular de problema ocurre con la suficiente frecuencia, puede valer la pena expresar las instancias del problema como oraciones en un lenguaje simple. Esto hace posible construir un intérprete que resuelva el problema interpretando estas oraciones.

1. Principios de diseño del patrón de intérprete

1, expresión abstracta (IExpression): define el método abstracto de interpretación;

2, Expresión Terminal (TerminalExpression): realiza la operación de interpretación relacionada con el símbolo terminal en la gramática;

3, Expresión no terminal (NonterminalExpression): realizar las operaciones de interpretación relacionadas con los no terminales en la gramática;

4. Contexto: información global fuera del intérprete.

2. Ejemplo sencillo

Utilice el modo de intérprete para encapsular operaciones de suma, resta, multiplicación y división.

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());
    }
}

imagen-20210330121616301

3. Evaluación del Modo Intérprete

El modo de intérprete aumenta la complejidad del sistema con la complejidad de la gramática. Buena extensibilidad, gramática simple fácil de implementar.

Supongo que te gusta

Origin blog.csdn.net/qq_40589204/article/details/119914758
Recomendado
Clasificación