设计模式-解释器模式

75 阅读3分钟

一、解释器模式介绍

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

文法句子的概念同编译原理中的描述相同,“文法”指语言的语法规则,而“句子”是语言集中的元素。

解释器模式角色:

  • 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()
  • 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  • 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。

此处我们的诉求:

  • 通过代码结构对解释器模式进行了解即可

二、解释器模式使用

2.1 示例关系:

2.2 代码实现:

/* *
 * 1. 抽象表达式类。
 */

interface AbstractExpression {
    /* *
     * 解释方法。
     */

    void interpret(String info);
}



/* *
 * 2. 终结符表达式类。
 */

class TerminalExpression implements AbstractExpression {

    @Override
    public void interpret(String info) {
        // 对终结符表达式的处理。
    }
}



/* *
 * 3. 非终结符表达式类。
 */

class NonterminalExpression implements AbstractExpression {

    private AbstractExpression exp1;
    private AbstractExpression exp2;

    @Override
    public void interpret(String info) {
        //非对终结符表达式的处理
    }
}



/* *
 * 4. 环境类。
 */

class Context {

    private AbstractExpression exp;

    public Context() {
        //数据初始化
    }

    public void operation(String info) {
        //调用相关表达式类的解释方法
    }
}

三、解释器模式总结

优点

  • 扩展性好。由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
  • 容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

缺点

  • 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  • 会引起类膨胀。解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  • 可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

应用场景

  • 编译器、运算表达式计算、正则表达式等。
  • Spring SpelExpressionParser源码使用到了该模式。

注意

  • 解释器模式在实际的软件开发中使用比较少,因为它会引起效率、性能以及维护等问题。如果碰到对表达式的解释,在 Java 中可以用 Expression4JJepJava expression parser)等来设计。

四、结束语

“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶