设计模式(二十一)—— 解释器模式

解释器模式

定义

给定一门语言,定义它的文法的一种表示,并定义一个解释器来解释语言中的句子。

  • AbstractExpression:抽象解释器,定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  • TerminalExpression:终结符表达式,实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例对应不同的终结符。
  • NonterminalExpression:非终结符表达式,文法中每条规则对应一个非终结符表达式。非终结符表达式根据逻辑的复杂度而增加,原则上每个文法规则都对应一个终结符表达式。
  • Context:环境角色,通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。

抽象表达式是生成语法集合(也叫语法树)的关键。每个语法集合完成指定语法解析任务,他是通过递归调用的方式,最终由最小的语法单元解析完成。

通用代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class Expression {
public abstract Object interpreter(Context context);
}

public class TerminalExpression extends Expression {
@Override
public Object interpreter(Context context) {
return null;
}
}

public class NontermianlExpression extends Expression {

public NontermianlExpression(Expression... expressions){
// 每个非终结符表达式都会对其他表达式产生依赖
}

@Override
public Object interpreter(Context context) {
return null;
}
}

优点

扩展性好,修改语法规则,只要修改相应的非终结符表达式就可以,如扩展语法,则只要增加非终结符类就可以。

缺点

  1. 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  2. 会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  3. 可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

注意事项

尽量不要在重要的模块中使用解释器模式,否则维护是一个很大的问题,在项目中可以使用其他的脚本语言来提解释器模式,弥补java的不足。

代码:GitHub


欢迎关注公众号:
公众号微信

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
显示 Gitment 评论