定义:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
如同开发了一个编程语言会脚本给自己、别人用。
就是用‘迷你语言’来表现程序要解决的问题,用迷你语言写成‘迷你程序’来表现具体的问题。
针对问题:
一种特定类型的问题发生的频率足够高,就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树。
例如:
1.正则表达式,用于搜索匹配的字符;或,判断一个字符是否符合规定的格式。
这些需求都非常类似,与其为每一个特定的需求都写一个算法函数,不如使用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了带匹配字符串的集合。
解释器为正则表达式定义了一个文法:如何表示一个特定的正则表达式,如何解释这个正则表达式。
2.IE、Firefox……浏览器也在解释HTML文法,将HTML标记文本转换成网页格式显示给用户。
3.其他。只要是可以用语言来描述的,都可应用解释器模式。人工智能,机器人……
优点:
很容易地改变、扩展文法。因为该模式使用类来表示文法规则,可使用继承来改变或扩展改文法。
比较容易实现文法。以为定义抽象语法树中各个节点的类的实现答题类似,这些类都易于直接编写。
通过继承抽象表达式的方式,由于依赖倒转沿着,使文法的扩展、维护更加方便。
缺点:
为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理、维护。
Tip:
建议当文法非常复杂时,使用其他的技术,如:语法分析程序、编译器生成器来处理。
结构图:
AbstractExpression
TerminalExpression:实现抽象表达式中所要求的接口,主要是一个interpret()。文法中每一个终结符都有一个具体终结表达式与之相对应。
NonterminalExpression:通过实现抽象表达式的interpret()实现解释操作。解释操作以递归方式调用代表R1、R2、R3……Rn中各个符号的实例变量。
Context
客户端:构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作。
结果:
示例:
音乐解释器
如果需要增加一个文法时。如,添加演奏速度……,只需添加一个速度类。客户端添加case即可。但是改动了客户端。
优化:在客户端那里应用:简单工厂+反射