自学教程 学编程从这里开始

解释器模式

《解释器模式》|设计模式系列第24篇

系列:行为型模式 · 解释器模式(Interpreter Pattern)
关键词:语法规则、表达式树、文法解析、递归求值、终结符、非终结符

一、什么是解释器模式

解释器模式(Interpreter Pattern):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

属于行为型设计模式。

简单理解:
把一门简易语言的文法拆分为表达式对象,构建抽象语法树。每个表达式对象都拥有 interpret() 求值方法;通过递归调用完成表达式计算。
例子:简单四则运算表达式 10 + 5 - 3,拆成数字终结符表达式、加减非终结符表达式,递归遍历语法树算出结果。

核心意图
将文法规则封装成表达式类,构建语法树,用来解析和计算自定义表达式。

适用场景

  1. 需要实现一门简单语言/表达式引擎
  2. 文法规则数量有限,且不会频繁大规模变动
  3. 脚本引擎、规则表达式、数学表达式解析、SQL解析简化版

⚠️ 缺点预警:文法复杂时,类数量爆炸;递归调用性能较差;复杂文法不推荐手写解释器,优先使用成熟解析库。

二、UML结构图

角色划分:

  1. AbstractExpression(抽象表达式):定义 interpret() 解释接口
  2. TerminalExpression(终结符表达式):实现文法中基础元素,叶子节点,无下级表达式
  3. NonTerminalExpression(非终结符表达式):文法运算规则,持有子表达式,递归解释
  4. Context(上下文):全局信息,变量、输入、存储解释过程数据
  5. Client(客户端):构建抽象语法树,调用 interpret()

三、Java 完整示例

场景:简单数字加法运算,计算表达式,代码全部使用英文。

// AbstractExpression
public abstract class Expression {
    public abstract int interpret();
}

// TerminalExpression
public class NumberExpression extends Expression {
    private int value;

    public NumberExpression(int value) {
        this.value = value;
    }

    @Override
    public int interpret() {
        return value;
    }
}

// NonTerminalExpression
public class AddExpression extends Expression {
    private Expression left;
    private Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

public class SubExpression extends Expression {
    private Expression left;
    private Expression right;

    public SubExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        // Build expression: 10 + 5 - 3
        Expression num10 = new NumberExpression(10);
        Expression num5 = new NumberExpression(5);
        Expression num3 = new NumberExpression(3);

        Expression add = new AddExpression(num10, num5);
        Expression sub = new SubExpression(add, num3);

        int result = sub.interpret();
        System.out.println("Result = " + result);
    }
}

运行输出:

Result = 12

四、优缺点总结

✅ 优点

  1. 文法规则独立封装,新增文法只需新增表达式类,符合开闭原则
  2. 表达式语法树结构直观,便于扩展简单语法
  3. 解释逻辑分散到各个表达式类,单一职责

❌ 缺点

  1. 文法复杂会产生大量表达式类,类膨胀
  2. 递归解释,性能较差,深度大容易栈溢出
  3. 维护复杂文法成本高

五、框架源码应用

  • Spring EL(Spring Expression Language)底层思想
  • MyBatis ${} 动态SQL表达式解析
  • OGNL 表达式引擎

六、小结

解释器模式核心:把文法拆成终结符、非终结符表达式,构建语法树,递归调用 interpret 完成表达式求值。
⚠️ 使用限制:只适合简单文法;业务开发极少手写,复杂表达式直接使用成熟表达式引擎。

标签:

0 条笔记