解释器模式 (Interpreter Pattern)

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解释器模式 (Interpreter Pattern)相关的知识,希望对你有一定的参考价值。

解释器模式 (Interpreter Pattern)

解释器模式的定义

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

解释器模式的优点

  1. 扩展性好。解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
  2. 容易实现。在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

解释器模式的缺点

  1. 执行效率较低。解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  2. 会引起类膨胀。每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。
  3. 可应用的场景比较少。在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

解释器模式的结构

解释器模式包含以下主要角色。

  1. 抽象表达式(Abstract Expression)角色:抽象解释器,定义解释器的接口,约定解释器的解释操作,具体的解释器分别由TerminalExpression和NonterminalExpression完成。主要包含解释方法 interpret()。
  2. 终结符表达式(Terminal Expression)角色:用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。
  3. 非终结符表达式(Nonterminal Expression)角色:用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
  4. 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  5. 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

解释器模式的实现

一般实现

/**
 * 抽象表达式
 */
public abstract class Expression {
    /**
     * 每个表达式必须有一个解析任务
     */
    public abstract void interpreter(Context context);
}
/**
 * 终结符表达式类
 */
public class TerminalExpression extends Expression {


    /**
     * 每个表达式必须有一个解析任务
     */
    @Override
    public void interpreter(Context context) {
        System.out.println("终结符表达式");
    }
}
/**
 * 非终结符表达式
 */
public class NonterminalExpression extends Expression {

    /**
     * 每个表达式必须有一个解析任务
     */
    @Override
    public void interpreter(Context ctx) {
        System.out.println("非终结符表达式");
    }
}
/**
 * Context环境角色
 */
public class Context {

}
public static void main(String[] args) {
    Context context = new Context();
    List<Expression> list = new ArrayList<>();
    list.add(new TerminalExpression());
    list.add(new NonterminalExpression());
    list.add(new TerminalExpression());
    list.add(new TerminalExpression());

    for (Expression abstractExpression : list) {
        abstractExpression.interpreter(context);
    }
}

解释器模式的适用场景

  • 重复发生的问题可以使用解释器模式
  • 一个简单语法需要解释的场景

本文主要参考:

  1. 小傅哥的《重学Java模式》
  2. 《C语言中文网》设计模式的相关内容
  3. 《设计模式之禅》第二版 秦小波

以上是关于解释器模式 (Interpreter Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

解释器模式(Interpreter Pattern)

Behavioral模式之Interpreter模式

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

设计模式---领域规则模式之解析器模式(Interpreter)

解释器模式(Interpreter)

设计模式之Interpreter模式(笔记)