`
guafei
  • 浏览: 328256 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

解释器模式

阅读更多
一、引子
  其实没有什么好的例子引入解释器模式,因为它描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发编译器中;在实际应用中,我们可能很少碰到去构造一个语言的文法的情况。
  
  虽然你几乎用不到这个模式,但是看一看还是能受到一定的启发的。
  
  二、定义与结构
  解释器模式的定义如下:定义语言的文法,并且建立一个解释器来解释该语言中的句子。它属于类的行为模式。这里的语言意思是使用规定格式和语法的代码。
  
  在GOF的书中指出:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。而且当文法简单、效率不是关键问题的时候效果最好。
  
  这也就是解释器模式应用的环境了。
  
  让我们来看看神秘的解释器模式是由什么来组成的吧。
  
  1) 抽象表达式角色:声明一个抽象的解释操作,这个接口为所有具体表达式角色(抽象语法树中的节点)都要实现的。
  
   什么叫做抽象语法树呢?《java与模式》中给的解释为:抽象语法树的每一个节点都代表一个语句,而在每个节点上都可以执行解释方法。这个解释方法的执 行就代表这个语句被解释。由于每一个语句都代表这个语句被解释。由于每一个语句都代表一个常见的问题的实例,因此每一个节点上的解释操作都代表对一个问题 实例的解答。
  
  2) 终结符表达式角色:具体表达式。
  
  a) 实现与文法中的终结符相关联的解释操作
  
  b) 而且句子中的每个终结符需要该类的一个实例与之对应
  
  3) 非终结符表达式角色:具体表达式。
  
  a) 文法中的每条规则R::=R1R2…Rn都需要一个非终结符表带式角色
  
  b) 对于从R1到Rn的每个符号都维护一个抽象表达式角色的实例变量
  
  c) 实现解释操作,解释一般要递归地调用表示从R1到Rn的那些对象的解释操作
  
  4) 上下文(环境)角色:包含解释器之外的一些全局信息。
  
  5) 客户角色:
  
  a) 构建(或者被给定)表示该文法定义的语言中的一个特定的句子的抽象语法树
  
  b) 调用解释操作
  
  放上张解释器结构类图吧,这也是来自于GOF的书中。
  
  对每一个角色都给出了详细的职责,而且在类图中给出五个角色之间的关系。这样实现起来也不是很困难了,下面举了一个简单的例子,希望能加深你对解释器模式的理解。

三、举例
  来举一个加减乘除的例子吧,实现思路来自于《java与模式》中的例子。每个角色的功能按照上面提到的规范来实现。
  
  //上下文(环境)角色,使用HashMap来存储变量对应的数值
  
  class Context
  {
  private Map valueMap = new HashMap();
  public void addValue(Variable x , int y)
  {
  Integer yi = new Integer(y);
  valueMap.put(x , yi);
  }
  
  public int LookupValue(Variable x)
  {
  int i = ((Integer)valueMap.get(x)).intValue();
  return i ;
  }
  }
  
  //抽象表达式角色,也可以用接口来实现
  
  abstract class Expression
  {
  public abstract int interpret(Context con);
  }
  
  //终结符表达式角色
  
  class Constant extends Expression
  {
  private int i ;
  public Constant(int i)
  {
  this.i = i;
  }
  
  public int interpret(Context con)
  {
  return i ;
  }
  }
  
  class Variable extends Expression
  {
  public int interpret(Context con)
  {
  //this为调用interpret方法的Variable对象
  return con.LookupValue(this);
  }
  }

//非终结符表达式角色
  
  class Add extends Expression
  {
  private Expression left ,right ;
  public Add(Expression left , Expression right)
  {
  this.left = left ;
  this.right= right ;
  }
  
  public int interpret(Context con)
  {
  return left.interpret(con) + right.interpret(con);
  }
  }
  
  class Subtract extends Expression
  {
  private Expression left , right ;
  public Subtract(Expression left , Expression right)
  {
  this.left = left ;
  this.right= right ;
  }
  
  public int interpret(Context con)
  {
  return left.interpret(con) - right.interpret(con);
  }
  
  }
  
  class Multiply extends Expression
  {
  private Expression left , right ;
  public Multiply(Expression left , Expression right)
  {
  this.left = left ;
  this.right= right ;
  }
  public int interpret(Context con)
  {
  return left.interpret(con) * right.interpret(con);
  }
  }
  
  class Division extends Expression
  {
  private Expression left , right ;
  public Division(Expression left , Expression right)
  {
  this.left = left ;
  this.right= right ;
  }
  
  public int interpret(Context con)
  {
  try{
  return left.interpret(con) / right.interpret(con);
  }catch(ArithmeticException ae)
  {
  System.out.println("被除数为0!");
  return -11111;
  }
  }
  }
  
  //测试程序,计算 (a*b)/(a-b+2)
  
  public class Test
  {
  private static Expression ex ;
  private static Context con ;
  public static void main(String[] args)
  {
  con = new Context();
  //设置变量、常量
  Variable a = new Variable();
  Variable b = new Variable();
  Constant c = new Constant(2);
  //为变量赋值
  con.addValue(a , 5);
  con.addValue(b , 7);
  //运算,对句子的结构由我们自己来分析,构造
  ex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c));
  System.out.println("运算结果为:"+ex.interpret(con));
  }
  }

解释器模式并没有说明如何创建一个抽象语法树,因此它的实现可以多种多样,在上面我们是直接在Test中提供的,当然还有更好、更专业的实现方式。
  
  对于终结符,GOF建议采用享元模式来共享它们的拷贝,因为它们要多次重复出现。但是考虑到享元模式的使用局限性,我建议还是当你的系统中终结符重复的足够多的时候再考虑享元模式。
  
  四、优缺点
  解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法。一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。而且在解释器中不同的规则是由不同的类来实现的,这样使得添加一个新的语法规则变得简单。
  
  但是解释器模式对于复杂文法难以维护。可以想象一下,每一个规则要对应一个处理类,而且这些类还要递归调用抽象表达式角色,多如乱麻的类交织在一起是多么恐怖的一件事啊!
  
  五、总结
  这样对解释器模式应该有了些大体的认识了吧,由于这个模式使用的案例匮乏,所以本文大部分观点直接来自于GOF的原著。只是实例代码是亲自实现并调试通过的。
分享到:
评论

相关推荐

    设计模式之解释器模式Java版本实现

    解释器模式是一种行为设计模式,它允许我们定义一个语言的语法,并提供一个解释器来解析该语言中的句子。在Java中实现解释器模式,我们可以创建一个抽象表达式接口,然后为每种特定的语法结构创建一个具体表达式类。...

    解释器模式例子

    解释器模式是一种设计模式,它允许我们为特定的语言或表达式定义一个解析规则,并通过这个规则来解释执行这些语言或表达式。在本例子中,我们将深入探讨如何使用解释器模式来实现一个能够理解并执行机器人指令的系统...

    设计模式之解释器模式(Interpreter Pattern)

    **设计模式之解释器模式(Interpreter Pattern)** 解释器模式是一种行为设计模式,它提供了一种方式来表示语言的语法,并实现一个解释器用于解析这种语法的语句。这种模式通常用于小型、特定领域的语言(DSL)实现,...

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

    **解释器模式(Interpreter)**是一种行为设计模式,它允许我们定义一种语言并为其创建一个解释器。在软件工程中,这种模式常用于处理简单的语言或表达式,例如配置文件、计算公式或者简单的脚本语言。通过使用解释...

    解释器模式代码示例

    解释器模式是一种设计模式,它允许我们为特定的语言或表达式定义一个解析规则,并提供一个解释器来执行这些规则。这种模式在处理简单的语言或结构化表达式时特别有用,例如配置文件、简单的数学表达式或者编程语言的...

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

    解释器模式(Interpreter Pattern)是25种经典设计模式之一,主要应用于创建一个解析语言或者表达式的方式。在本篇文章中,我们将深入探讨解释器模式的概念、结构以及其在实际开发中的应用。 解释器模式是一种行为...

    [行为型模式] 解释器模式的理解

    **行为型模式——解释器模式** 解释器模式是一种设计模式,它允许我们为特定语言创建一个解析器。这种模式在处理简单的语言或表达式时特别有用,例如配置文件、简单的编程语言或者数学表达式。解释器模式的核心在于...

    第十七讲:解释器模式

    解释器模式是一种设计模式,它允许我们为特定的语言或表达式定义一个解析规则。在软件工程中,这种模式常用于构建简单的语言解释器或者执行基于某种规则的逻辑。本讲将深入探讨解释器模式的原理、结构以及在实际开发...

    设计模式-解释器模式(讲解及其实现代码)

    **解释器模式**是一种行为设计模式,它提供了一种方式来表示语言的语法,并通过类和对象解析这种语法。在编程领域,解释器模式常用于创建简单的语言或表达式解析器,例如配置文件、计算器应用或者SQL查询的简化版本...

    72丨解释器模式:如何设计实现一个自定义接口告警规则功能?1

    解释器模式是一种设计模式,用于创建能解析特定语言或规则集的解释器。这种模式的核心在于定义一个表达式的抽象语法树(AST),并提供一个解释器来遍历这棵树,执行与之相关的操作。在 GoF 的《设计模式》书中,解释...

    Ansy.rar_C语言解释器_解释 语言_解释器_解释器模式_语言解释器

    《C语言解释器的实现与解释器模式解析》 在编程世界中,编译器和解释器是两种关键的工具,它们将高级编程语言转换为机器可以理解的指令。本篇我们将聚焦于“C语言解释器”的实现,以及在设计过程中所采用的“解释器...

    java23中设计模式之解释器模式

    java设计模式之解释器模式,自己根据理解还有参考弄的,看不懂的可以细聊

    第19章_解释器模式.ppt

    如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实例表述为一个语言中的句子,因此可以构建一...解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。

    Android解释器模式简单Demo

    Android解释器模式简单Demo,通过实现计算器四则运算,加减的逻辑,来领悟解释器这种模式的设计,同步博文:http://blog.csdn.net/qq_28690547/article/details/50707916

    c++设计模式-行为型模式-解释器模式

    c++设计模式-行为型模式-解释器模式;qt工程;c++简单源码; 解释器(Interpreter)模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式...

    解释器模式案例源码Demo

    解释器模式,也被称为解析器模式,是一种设计模式,它允许我们定义一套语言的文法,并为这个语言提供解释器。这种模式常用于构建小型、特定领域的语言,比如配置文件、简单的脚本或计算器等。在Java、Python等面向...

    解释器模式(Interpreter)原理图

    解释器模式(Interpreter Pattern)是一种行为型设计模式,它用于定义一个语言的文法,并解析语言中的表达式。具体来说,解释器模式通过定义一个解释器来解释语言中的表达式,从而实现对语言的解析和执行。 在解释...

    【Java设计模式】解释器模式

    该应用程序使用Java中的解释器模式来解析和评估算术表达式,如“5 + 3 * 2”。在这里,解释器将表达式的每个部分转换为表示数字和操作的对象。这些对象遵循定义的语法,使应用程序能够根据算术规则正确理解和计算...

Global site tag (gtag.js) - Google Analytics