设计模式(二十四):解释器模式(Interpreter Pattern)

Published on 2024-04-12 13:37 in 分类: 博客 with 狂盗一枝梅
分类: 博客

一、解释器模式的定义

给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。(Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.)

要注意的是,解释器模式在实际的系统开发中使用得非常少,几乎是用不到,甚至在某些书里直接将其从23种设计模式中删除。。。如果非得使用,可以考虑开源框架下Expression4J、MESP(Math Expression String Parser)、Jep等开源的解析工具包。

解释器模式的通用类图如下所示

解释器模式-解释器模式通用类图.drawio
  1. 抽象解释器(Abstract Expression):声明抽象的解释操作,定义了解释器的接口。
  2. 终结符解释器(Terminal Expression):实现抽象解释器接口,表示语言中的终结符(即不可再分的基本语法单元),并提供解释和执行终结符的方法。
  3. 非终结符解释器(Non-terminal Expression):实现抽象解释器接口,表示语言中的非终结符(即由终结符组成的复合语法单元),并提供解释和执行非终结符的方法。
  4. 上下文(Context):包含解释器解释和执行的上下文环境,提供相关的信息和数据。

这解释器模型定义拗口,其实也不简单,一般小项目用不到,一般在大中型的框架型项目能够找到它的身影,如一些数据分析工具、报表设计工具、科学计算工具等。

二、解释器模式举例

为了更好的说明下解释器模型,来举一个例子:数学表达式解析器。假设我们有一个数学表达式字符串,例如 "2 + 3 - 1",我们希望通过解释器模式来解析并计算该表达式的结果。

首先,我们定义抽象解释器接口 Expression,它声明了解释方法 interpret

interface Expression {
    int interpret();
}

然后,我们创建终结符解释器类 NumberExpression,它表示一个数字:

class NumberExpression implements Expression {
    private int number;

    public Number {
        this.number = number;
    }

    public int interpret() {
        return number;
    }
}

接下来,我们创建非终结符解释器类 AdditionExpressionSubtractionExpression,分别表示加法和减法运算:

class AdditionExpression implements Expression {
    private Expression leftExpression;
    private Expression rightExpression;

    public Addition {
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    public int interpret() {
        return leftExpression.interpret() + rightExpression.interpret();
    }
}

class SubtractionExpression implements Expression {
    private Expression leftExpression;
    private Expression rightExpression;

    public Subtraction {
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    public int interpret() {
        return leftExpression.interpret() - rightExpression.interpret();
    }
}

现在,我们可以使用解释器模式来解析并计算数学表达式。假设我们有一个表达式字符串 "2 + 3 - 1",我们将其转换为相应的解释器对象,并调用解释方法进行求值:

public class Main {
    public static void main(String[] args) {
        // 创建解释器对象:2 + 3 - 1
        Expression expression = new Subtraction,
                new Number
            ),
            new Number
        );

        // 解析并计算表达式
        int result = expression.interpret();

        System.out.println("Result: " + result);
    }
}

运行代码,输出结果为:

Result: 4

由于此处案例过于简单,所以并没有使用Context类。

三、总结

作为几乎从23种设计模式中被剔除的一种设计模式,极少在项目中被使用到,了解它是个什么东西即可。如果非得使用,可以考虑开源框架下Expression4J、MESP(Math Expression String Parser)、Jep等开源的解析工具包。


#设计模式
目录