设计模式--19、解释器模式

定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。

类型:行为类模式

类图:

解释器模式是一个比较少用的模式,本人之前也没有用过这个模式。下面我们就来一起看一下解释器模式。

解释器模式的结构

  • 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器NonterminalExpression完成。
  • 终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。终结符一半是文法中的运算单元,比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
  • 非终结符表达式:文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
  • 环境角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。

代码实现

[java] view plain copy

  1. class Context {}
  2. abstract class Expression {
  3. public abstract Object interpreter(Context ctx);
  4. }
  5. class TerminalExpression extends Expression {
  6. public Object interpreter(Context ctx){
  7. return null;
  8. }
  9. }
  10. class NonterminalExpression extends Expression {
  11. public NonterminalExpression(Expression...expressions){
  12. }
  13. public Object interpreter(Context ctx){
  14. return null;
  15. }
  16. }
  17. public class Client {
  18. public static void main(String[] args){
  19. String expression = "";
  20. char[] charArray = expression.toCharArray();
  21. Context ctx = new Context();
  22. Stack<Expression> stack = new Stack<Expression>();
  23. for(int i=0;i<charArray.length;i++){
  24. //进行语法判断,递归调用
  25. }
  26. Expression exp = stack.pop();
  27. exp.interpreter(ctx);
  28. }
  29. }

文法递归的代码部分需要根据具体的情况来实现,因此在代码中没有体现。抽象表达式是生成语法集合的关键,每个非终结符表达式解释一个最小的语法单元,然后通过递归的方式将这些语法单元组合成完整的文法,这就是解释器模式。

解释器模式的优缺点

解释器是一个简单的语法分析工具,它最显著的优点就是扩展性,修改语法规则只需要修改相应的非终结符就可以了,若扩展语法,只需要增加非终结符类就可以了。

但是,解释器模式会引起类的膨胀,每个语法都需要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来非常多的麻烦。同时,由于采用递归调用方法,每个非终结符表达式只关心与自己相关的表达式,每个表达式需要知道最终的结果,必须通过递归方式,无论是面向对象的语言还是面向过程的语言,递归都是一个不推荐的方式。由于使用了大量的循环和递归,效率是一个不容忽视的问题。特别是用于解释一个解析复杂、冗长的语法时,效率是难以忍受的。

解释器模式的适用场景

在以下情况下可以使用解释器模式:

  • 有一个简单的语法规则,比如一个sql语句,如果我们需要根据sql语句进行rm转换,就可以使用解释器模式来对语句进行解释。
  • 一些重复发生的问题,比如加减乘除四则运算,但是公式每次都不同,有时是a+b-c*d,有时是a*b+c-d,等等等等个,公式千变万化,但是都是由加减乘除四个非终结符来连接的,这时我们就可以使用解释器模式。

注意事项

解释器模式真的是一个比较少用的模式,因为对它的维护实在是太麻烦了,想象一下,一坨一坨的非终结符解释器,假如不是事先对文法的规则了如指掌,或者是文法特别简单,则很难读懂它的逻辑。解释器模式在实际的系统开发中使用的很少,因为他会引起效率、性能以及维护等问题。

时间: 2024-10-08 08:53:18

设计模式--19、解释器模式的相关文章

大话设计模式_解释器模式(Java代码)

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 简单描述:一个AbstractExpression类,多个子类,存在一个Interpret方法,转义Context对象的信息.客户端根据信息实例化不同的Expression类,并调用其转义方法(这个过程可以使用简单工厂+反射进行) 大话设计模式中的截图: 代码例子: 假设HTML代码解释器: (1)第一类标签<HTML>(开始)/<HEAD>(头信息)/<BODY&g

设计模式之解释器模式(Interpreter)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

GOF23设计模式之解释器模式和访问器模式的理解

设计模式之解释器模式Interpreter      是一种不常用的设计模式      用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的编译器和解释器设计.      当我们需要开发一种新的语言时,可以考虑使用解释器模式.      尽量不要使用解释器模式,后期维护会有很大麻烦.在项目中可以使用jruby,Groovy,java的js引擎来代替解释器的作用,弥补java语言的不足. 开发中常见的场景:      EL表达式的处理      正则表达式解释器      SQL语

C#设计模式:解释器模式(Interpreter Pattern)

一,C#设计模式:解释器模式(Interpreter Pattern) 1,解释器模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象为语法规则的问题”才适合使用解释器模式2,解释器设计模式每个解释的类有自己的规则,并且与其他业务规则不冲突 二,如下代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; u

Head First设计模式之解释器模式

一.定义 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子. 主要解决:对于一些固定文法构建一个解释句子的解释器. 何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题. 如何解决:构件语法树,定义终结符与非终结符. 二.结构 组成: AbstractExpression(抽象表达式):定义解释器的接口,约定解释器的解释操作. Termi

php设计模式之解释器模式

解释器设计模式用于分析一个实体的关键元素,并且针对每个元素都提供自己的解释或相应的动作. <?php /** * 解释器模式 */ class User { protected $_username; public function __construct($username) { $this->_username = $username; } public function getProfilePage() { $profile = "<h2>I like never

行为型设计模式之解释器模式(Interpreter)

结构 意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 适用性 当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式.而当存在以下情况时该模式效果最好: 该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理.此时语法分析程序生成器这样的工具是更好的选择.它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间. 效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现

【GOF23设计模式】解释器模式 &amp; 访问者模式

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_解释器模式.访问者模式.数学表达式动态解析库式 1.解释器模式Interpreter  2.访问者模式Visitor 

【Unity与23种设计模式】解释器模式(Interpreter)

GoF中定义: "定义一个程序设计语言所需要的语句,并提供解释来解析(执行)该语言." 传统上,执行程序代码通常通过两种方式 第一种:编译程序 第二种:解释器 常见的使用解释器的程序设计语言 包含流行与网页设计领域中的脚本语言 如JavaScript.PHP.Ruby等 这些程序代码经过一般文本编辑器编写完成后放入指定的位置 就可以由应用程序中的解释器直接执行 包括Lua Unity中 编写好的脚本程序执行之前会被UnityEngine编译过 严格来说不算是解释器模式 但与十几年前的开

设计模式之解释器模式--- Pattern Interpreter

模式的定义 类型 行为类 模式的使用场景 优点 缺点 UML类图 角色介绍 模式的通用源码 输出结果 Android源码中的模式实现 杂谈 参考资料 (1).设计模式之禅-第27章 解释器模式 (2)解释器模式 https://github.com/simple-android-framework/android_design_patterns_analysis