美文网首页
设计模式之十四——解释器模式

设计模式之十四——解释器模式

作者: dd299 | 来源:发表于2019-07-01 11:17 被阅读0次

    原文传送门

    1 介绍

    解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

    1.1 什么是解释器模式

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

    1.2 解决了什么问题

    这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
    如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

    2 原理

    • 参与者
      • AbstractExpression——抽象解释器。具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和Non-terminalExpression完成。
      • TerminalExpression——终结符表达式。实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
      • NonterminalExpression——非终结符表达式。文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
      • Context——环境角色。具体到我们的例子中是采用HashMap代替。

    2.1 uml图

    解释器模式的通用类图

    2.2 代码示例

    Expression代码示例

    public abstract class Expression {
         //每个表达式必须有一个解析任务
         public abstract Object interpreter(Context  ctx);
    }
    

    TerminalExpression代码示例

    public class TerminalExpression extends Expression {
         //通常终结符表达式只有一个,但是有多个对象
         public Object interpreter(Context ctx) {
                 return null;
         }
    }
    

    NonterminalExpression代码示例

    public class NonterminalExpression extends Expression {
         //每个非终结符表达式都会对其他表达式产生依赖
         public NonterminalExpression(Expression... expression){
         }
    
         public Object interpreter(Context ctx) {
                 //进行文法处理
                 return null;
         }
    }
    }
    

    调用示例

    public class Client {
         public static void main(String[] args) {
              Context ctx = new Context();
              //通常定一个语法容器,容纳一个具体的表达式,通常为ListArray、LinkedList、Stack等类型
              Stack&Expression> stack = null; 
              for(;;){
                   //进行语法判断,并产生递归调用
              }          
              //产生一个完整的语法树,由各个具体的语法分析进行解析
              Expression exp = stack.pop();
              //具体元素进入场景
              exp.interpreter(ctx);
         }
    }
    

    2.3 优缺点

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

    • 缺点:

      1. 可利用场景比较少。
      2. 对于复杂的文法比较难维护。
      3. 解释器模式会引起类膨胀。
      4. 解释器模式采用递归调用方法。

    3 适用场景

    1. 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
    2. 一些重复出现的问题可以用一种简单的语言来进行表达。
    3. 一个简单语法需要解释的场景。

    5 总结

    解释器模式(Interpreter Pattern)是一种按照规定语法进行解析的方案,在现在项目中使用较少。
    尽量不要在重要的模块中使用解释器模式,否则维护会是一个很大的问题。在项目中可以使用shell、JRuby、Groovy等脚本语言来代替解释器模式,弥补Java编译型语言的不足。我们在一个银行的分析型项目中就采用JRuby进行运算处理,避免使用解释器模式的四则运算,效率和性能各方面表现良好。


    参考书籍及文章
    1.《Java与模式》,电子工业出版社,阎宏

    1. 《大话设计模式》,清华大学出版社,程杰
    2. 《设计模式——可复用面向对象软件的基础》,机械工业出版社,Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides
    3. 《Head First 设计模式(中文版)》,中国电力出版社
    4. 《图说设计模式》,https://design-patterns.readthedocs.io/zh_CN/latest/index.html
    5. 《设计模式之禅》,https://www.kancloud.cn/sstd521/design

    相关文章

      网友评论

          本文标题:设计模式之十四——解释器模式

          本文链接:https://www.haomeiwen.com/subject/enuucctx.html