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

xiaoxiao2021-02-28  49

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的算式运算,这种方式便是解释器。但是解释器很少会被使用,你应该也可以看到实现起来的复杂度。

解释器模式的优缺点:

优点:

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

缺点:

语法规则过多时,产生大量的语法类,使得这些语法类变得难以维护和管理
转载请注明原文地址: https://www.6miu.com/read-2613828.html

最新回复(0)