设计模式之解释器模式 (Interpreter Pattern)

解释器模式 (Interpreter Pattern)

📋 Research Summary

解释器模式用于定义特定领域语言(DSL)的语法解释。在正则表达式引擎、SQL 解析器、配置文件解析、数学表达式计算中有应用。但对于复杂语法,通常使用专门的解析器生成器(如 ANTLR、Yacc)替代。


🌱 逻辑原点

如果用户想搜索 "(apple OR banana) AND NOT rotten",你如何理解这个查询并转化为实际的过滤逻辑?如果明天用户想要 "NEAR" 操作符,你的代码需要怎么改?

自然语言需求与程序执行逻辑的矛盾:用户想用接近自然语言的方式表达,但程序只能执行确定的指令。

🧠 苏格拉底式对话

1️⃣ 现状:最原始的解法是什么?

用正则表达式或字符串处理:

python 复制代码
def search(query):
    if "AND" in query:
        parts = query.split("AND")
        return search(parts[0]) and search(parts[1])
    elif "OR" in query:
        parts = query.split("OR")
        return search(parts[0]) or search(parts[1])
    # ... 越来越复杂的字符串处理

优点 :简单快速,适合非常简单的场景。
问题:难以处理嵌套、优先级、复杂的语法规则。

2️⃣ 瓶颈:规模扩大 100 倍时会在哪里崩溃?

当查询语言变得复杂时:

  • 嵌套地狱(A AND (B OR (C AND D))) 这种嵌套用字符串处理几乎不可能
  • 优先级问题A AND B OR C(A AND B) OR C 还是 A AND (B OR C)
  • 扩展困难:增加新操作符需要修改所有解析代码
  • 无法复用:解析逻辑与执行逻辑混在一起

核心矛盾:我们需要一种系统化的方法来"理解"语言结构,而不是简单的字符串匹配。

3️⃣ 突破:必须引入什么新维度?

将语法规则建模为对象树

不是"处理字符串",而是"构建抽象语法树(AST)"。每个语法规则变成一个类,表达式被解析为一棵树,解释器通过遍历树来执行:

复制代码
查询字符串 --解析--> AST(AndExpression、OrExpression、NotExpression...)
                --遍历--> 执行结果

这就是解释器的本质:将语言语法建模为类层次结构,用树形结构表示表达式

📊 视觉骨架

例如
例如
例如
例如
包含
包含
表达式 Expression
终结符 Terminal
非终结符 Non-Terminal
数字 Number
变量 Variable
加法 Add
减法 Subtract
左表达式 Left
右表达式 Right

关键洞察:解释器模式将语法规则编码为类。终结符表达式(如数字、变量)没有子节点,非终结符表达式(如加减乘除)包含子表达式。解释就是递归遍历这棵树。

⚖️ 权衡模型

公式:

复制代码
Interpreter = 解决了领域语言的表达 + 牺牲了执行效率 + 增加了语法复杂度限制

代价分析:

  • 解决: 领域特定语言(DSL)、语法规则清晰可扩展、解析与执行分离、易于修改文法
  • 牺牲: 执行效率(递归解释比编译执行慢)、复杂文法难以维护
  • ⚠️ 增加: 类的数量(每个语法规则一个类)、内存开销(AST 树)、学习成本(需要理解文法和 AST)

使用建议:当需要定义简单的领域特定语言,且语法规则相对稳定时使用。对于复杂语法,建议使用 ANTLR 等专业解析器生成器。典型场景:配置文件解析、简单查询语言、规则引擎、数学表达式计算。

🔁 记忆锚点

python 复制代码
class Expression(ABC):
    """
    解释器的本质:将语法建模为对象树
    """
    
    @abstractmethod
    def interpret(self, context: Dict) -> float:
        """解释表达式"""
        pass

class Number(Expression):
    """终结符表达式:数字"""
    
    def __init__(self, value: float):
        self._value = value
    
    def interpret(self, context: Dict) -> float:
        return self._value

class Add(Expression):
    """非终结符表达式:加法"""
    
    def __init__(self, left: Expression, right: Expression):
        self._left = left
        self._right = right
    
    def interpret(self, context: Dict) -> float:
        # 递归解释子表达式
        return self._left.interpret(context) + self._right.interpret(context)

# 构建表达式树: (1 + 2) + 3
expr = Add(Add(Number(1), Number(2)), Number(3))
result = expr.interpret({})  # 递归计算

一句话本质: 解释器模式 = 将语法规则建模为类,用树形结构表示和计算表达式


相关推荐
用户938515635071 天前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-04-工厂方法模式(业务实战篇)
java·设计模式·工厂方法模式·架构设计·代码解耦
今天的砖头有点烫手啊2 天前
AI Agent 开发实战(十):Agent 设计模式(ReAct / Plan-Execute / Reflection)
人工智能·react.js·设计模式
董员外2 天前
RAG 系统进化论(十):可运营 RAG,从原型到长期运行的知识系统
人工智能·后端·设计模式
莫得感情 o2 天前
设计模式 15 · 模板方法模式
设计模式·模板方法模式
岭南灯火2 天前
前端通用交互式几何编辑器的开发经验
前端·设计模式·架构
岭南灯火2 天前
前端通用交互式几何编辑器的设计法则 7 - 设计模式与原则
前端·设计模式·架构
岭南灯火2 天前
前端通用交互式几何编辑器的设计法则 4 - 绘制、悬停与编辑
前端·设计模式·架构
岭南灯火2 天前
前端通用交互式几何编辑器的设计法则 6 - 配套设施与工程化
前端·设计模式·架构