Java设计模式(23)之解释器模式

Java中的解释器模式

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

类型:

通过中间类的行为型模式

解释器模式中的角色:

  • 抽象的解释器AbstractExpression:定义解释操作的接口,例如:interpret()
  • 终结符表达式TerminalExpression:为文法的终结符实现解释操作。例 : R1+R2=R,R1和R2便是终结符。
  • 非终结符表达式NonterminalExpression:为文法的非终结符实现解释操作。例: R1+R2=R,+ 便是终结符。
  • 环境对象Context:包含解释器以外的一些全局信息,一般用来存储终结符的具体信息。例 : R1=2,R2=3 用来存储具体的数值。

解释器模式的关系图:

这里写图片描述

解释器模式示例:

抽象的解释器AbstractExpression:

/**
 * Create by zhaihongwei on 2018/4/9
 * 抽象的解释器对象
 */
public interface Expression {

    /**
     * 定义解释器的接口
     */
    Integer interpret(Context context);
}

终结符表达式TerminalExpression:

/**
 * Create by zhaihongwei on 2018/4/9
 * 终结符表达式,用来解释运算符之外的表达式。
 */
public class NumberTerminalExpression implements Expression{

    @Override
    public Integer interpret(Context context) {
        return context.getTerminalValue(this);
    }
}

非终结符表达式NonterminalExpression:

/**
 * Create by zhaihongwei on 2018/4/9
 * 非终结符表达式,说白了就是运算符号,当然你也可以已经定义一种符号来进行某种运算
 * 例如  R1 # R2 , 将 # 解释为+ - * / 或者其他的运算。
 */
public class AddNonTerminalExpression implements Expression {

    private Expression left;
    private Expression right;

    public AddNonTerminalExpression(Expression left,Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public Integer interpret(Context context) {
        return context.getTerminalValue(left) + context.getTerminalValue(right);
    }
}

环境对象Context:

/**
 * Create by zhaihongwei on 2018/4/9
 * 环境角色
 */
public class Context {

    // 用来存储终结符的具体值
    public Map<Expression,Integer> map = new HashMap();

    public void addTerminalValue(Expression exp,Integer value) {
        map.put(exp,value);
    }

    public Integer getTerminalValue(Expression exp) {
        return map.get(exp);
    }
}

测试类:

/**
 * Create by zhaihongwei on 2018/4/9
 */
public class InterpreterTest {

    public static void main(String[] args) {

        // 解释表达式 : 1 # 3 ,将 # 解释为 + ,加法运算

        // 终结符表达式
        NumberTerminalExpression r1 = new NumberTerminalExpression();
        NumberTerminalExpression r2 = new NumberTerminalExpression();
        // 非终结符表达式
        AddNonTerminalExpression add = new AddNonTerminalExpression(r1,r2);

        // 初始化环境角色,并赋值
        Context context = new Context();
        context.addTerminalValue(r1,1);
        context.addTerminalValue(r2,3);

        // 输出解释器的结果
        System.out.println(add.interpret(context));

    }
}

测试结果:

1 # 3 通过解释器的最终结果为:4

总结:

通过解释器模式,做到了将1 # 3 表达式 解释为 1 + 3的算式运算,这种方式便是解释器。但是解释器很少会被使用,你应该也可以看到实现起来的复杂度。

解释器模式的优缺点:

优点:

  • 将每一种语法规则都定义为一个单独的类,实现单一职责。
  • 语法规则通过许多类的形式表示,容易扩展语法。

缺点:

  • 语法规则过多时,产生大量的语法类,使得这些语法类变得难以维护和管理

猜你喜欢

转载自blog.csdn.net/zhwyj1019/article/details/79866690