定义与特点
定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
简单概述为:我们可以定义一种语言或语法作为被分析对象,然后定义一个解析器来解析该语言对象。
- 文法:语法规则,如中文中的主、谓、宾。程序中json规则、xml语法规则
- 句子:语句中的元素,如中文句子,我是大学生。程序中json串,xml文档
- 语法树:语法树是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。
解释器模式的结构与组合模式相似,不过其包含的组成元素比组合模式多,而且组合模式是对象结构型模式,而解释器模式是类行为型模式。它是23种设计模式中最难理解,最少使用的一种设计模式。
参与角色
- 抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
- 终结符表达式(Terminal Expression):实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结表达式,但有多个实例,对应不同的终结符。
- 非终结符表达式(Nonterminal Expression):文法中的每条规则对应于一个非终结表达式,非终结符表达式根据逻辑的复杂程度而增加。
- 上下文(Context): 上下文环境类,包含解释器之外的全局信息 ,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
- 客户类(Client): 主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。
- 类结构图
类结构示例
定义抽象表达式类
interface AbstractExpression { public Object interpret(String info); // 解释方法 }
定义终结符表达式类
class TerminalExpression implements AbstractExpression { public Object interpret(String info) { // 对终结符表达式的处理 return null; } }
定义非终结符表达式类
class NonterminalExpression implements AbstractExpression { private AbstractExpression exp1; private AbstractExpression exp2; public Object interpret(String info) { // 非对终结符表达式的处理 return null; } }
环境类
class Context { private AbstractExpression exp; public Context() { // 数据初始化 } public void operation(String info) { // 调用相关表达式类的解释方法 } }
- 客户端调用类
总结
优点
- 解释器是一个简单的语法分析工具,它最显著的优点就是扩展性。
- 修改语法规则只需要修改相应的非终结符就可以了
- 若扩展语法,只需要增加非终结符类就可以了。
缺点
- 需要建大量的类,因为每一种语法都要建一个非终结符的类,会引起类膨胀。。
- 解释的时候采用递归调用方法,导致有时候函数的深度会很深,执行效率较低。
适用场景
- 当语言的文法较为简单,且执行效率不是关键问题时。
- 当问题重复出现,且可以用一种简单的语言来进行表达时。
- 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如 XML 文档解释。
注意:解释器模式在实际的软件开发中使用比较少,因为它会引起效率、性能以及维护等问题。