设计模式(解释器模式(Interpreter Pattern)结构|原理|优缺点|场景|示例

设计模式(分类) 设计模式(六大原则)

创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式

结构型(7种) 适配器模式 装饰器模式 代理模式 ​​​​​​外观模式 桥接模式 组合模式 享元模式

行为型(11种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 解释器 状态模式 访问者模式 中介者模式


解释器模式是一种行为型设计模式,它定义了一种语言的语法规则,并构建一个解释器来解释该语言中的句子。这里的 "语言" 可以是任何有固定语法规则的符号系统(如数学表达式、正则表达式、SQL 语法、配置文件格式等)。

核心思想:将复杂的语法规则拆分为简单的 "原子规则",通过组合这些原子规则来解析整个句子,实现对特定语言的解释执行。

模式结构

解释器模式包含 5 个核心角色,它们的协作关系形成语法解析的基础:

  1. 抽象表达式(Abstract Expression) 定义所有表达式的公共接口,声明一个interpret()方法,用于解释当前表达式。

  2. **终结符表达式(Terminal Expression)**实现抽象表达式接口,对应语法中的 "终结符"(语法中不可再分割的基本单位,如数学表达式中的数字、变量)。它是语法树的叶子节点,没有子表达式。

  3. 非终结符表达式(Non-terminal Expression) 实现抽象表达式接口,对应语法中的 "非终结符"(由多个终结符 / 非终结符组合而成的规则,如数学表达式中的a + b(x - y) * z)。它包含子表达式,解释时需要递归调用子表达式的interpret()方法。

  4. **上下文(Context)**存储解释器需要的全局信息(如变量的值、语法解析的中间结果),简化表达式之间的数据传递。

  5. 客户端(Client) 根据语法规则构建抽象语法树(由终结符和非终结符表达式组合而成),并调用根表达式的interpret()方法执行解释。

工作原理

  1. 定义语法规则 :明确目标语言的语法(如 "加法表达式由两个表达式和+组成")。
  2. 构建表达式类:为每个语法规则(终结符 / 非终结符)创建对应的表达式类。
  3. 生成抽象语法树(AST) :客户端将输入的句子(如3 + 5 * 2)转换为语法树,其中叶子节点是终结符表达式,非叶子节点是非终结符表达式。
  4. 执行解释 :从根节点开始调用interpret()方法,递归解析整个语法树,结合上下文信息得到最终结果。

优缺点

优点

  1. 易于扩展新语法:新增语法规则时,只需添加对应的表达式类,无需修改现有代码,符合 "开闭原则"。
  2. 语法规则清晰:每个语法规则对应一个表达式类,代码结构与语法规则一一对应,易于理解和维护。
  3. 灵活性高:可通过组合不同表达式实现复杂语法,适用于简单语言的解析。

缺点

  1. 不适合复杂语法:当语法规则复杂(如包含多层嵌套、大量运算符)时,会产生大量表达式类,导致系统臃肿("类爆炸")。
  2. 执行效率低:解释过程需要递归遍历语法树,且上下文频繁传递,复杂表达式的解析性能较差。
  3. 维护成本高:对于复杂语法,语法树的构建和调试难度较大。

适用场景

  1. 语法规则简单的场景:如简单的数学表达式(加减乘除)、布尔表达式(与或非)解析。
  2. 需要频繁扩展语法的场景:如自定义配置文件解析器(可动态新增配置语法)。
  3. 领域特定语言(DSL):如日志格式化语法、报表生成语法等小型专用语言的解析。
代码示例(以Java为例)

简单SQL WHERE条件解释器

java 复制代码
import java.util.*;

// 抽象表达式
interface SQLExpression {
    boolean interpret(Map<String, Object> row);
}

// 终结符表达式 - 等于条件
class EqualsExpression implements SQLExpression {
    private String column;
    private Object value;
    
    public EqualsExpression(String column, Object value) {
        this.column = column;
        this.value = value;
    }
    
    @Override
    public boolean interpret(Map<String, Object> row) {
        return row.containsKey(column) && row.get(column).equals(value);
    }
}

// 终结符表达式 - 大于条件
class GreaterThanExpression implements SQLExpression {
    private String column;
    private Comparable value;
    
    public GreaterThanExpression(String column, Comparable value) {
        this.column = column;
        this.value = value;
    }
    
    @Override
    public boolean interpret(Map<String, Object> row) {
        if (!row.containsKey(column)) return false;
        Object rowValue = row.get(column);
        return rowValue instanceof Comparable && 
               ((Comparable) rowValue).compareTo(value) > 0;
    }
}

// 非终结符表达式 - AND条件
class AndExpression implements SQLExpression {
    private SQLExpression left;
    private SQLExpression right;
    
    public AndExpression(SQLExpression left, SQLExpression right) {
        this.left = left;
        this.right = right;
    }
    
    @Override
    public boolean interpret(Map<String, Object> row) {
        return left.interpret(row) && right.interpret(row);
    }
}

// 非终结符表达式 - OR条件
class OrExpression implements SQLExpression {
    private SQLExpression left;
    private SQLExpression right;
    
    public OrExpression(SQLExpression left, SQLExpression right) {
        this.left = left;
        this.right = right;
    }
    
    @Override
    public boolean interpret(Map<String, Object> row) {
        return left.interpret(row) || right.interpret(row);
    }
}

// 非终结符表达式 - NOT条件
class NotExpression implements SQLExpression {
    private SQLExpression expression;
    
    public NotExpression(SQLExpression expression) {
        this.expression = expression;
    }
    
    @Override
    public boolean interpret(Map<String, Object> row) {
        return !expression.interpret(row);
    }
}

// SQL查询解释器
class SQLInterpreter {
    public List<Map<String, Object>> query(List<Map<String, Object>> data, SQLExpression whereClause) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> row : data) {
            if (whereClause.interpret(row)) {
                result.add(row);
            }
        }
        return result;
    }
}

// 客户端代码
public class SQLInterpreterDemo {
    public static void main(String[] args) {
        // 模拟数据
        List<Map<String, Object>> employees = new ArrayList<>();
        
        Map<String, Object> emp1 = new HashMap<>();
        emp1.put("id", 1);
        emp1.put("name", "Alice");
        emp1.put("age", 25);
        emp1.put("salary", 50000);
        emp1.put("department", "IT");
        employees.add(emp1);
        
        Map<String, Object> emp2 = new HashMap<>();
        emp2.put("id", 2);
        emp2.put("name", "Bob");
        emp2.put("age", 30);
        emp2.put("salary", 60000);
        emp2.put("department", "HR");
        employees.add(emp2);
        
        Map<String, Object> emp3 = new HashMap<>();
        emp3.put("id", 3);
        emp3.put("name", "Charlie");
        emp3.put("age", 35);
        emp3.put("salary", 70000);
        emp3.put("department", "IT");
        employees.add(emp3);
        
        // 构建查询条件: department = 'IT' AND salary > 55000
        SQLExpression deptIT = new EqualsExpression("department", "IT");
        SQLExpression highSalary = new GreaterThanExpression("salary", 55000);
        SQLExpression whereClause = new AndExpression(deptIT, highSalary);
        
        // 执行查询
        SQLInterpreter interpreter = new SQLInterpreter();
        List<Map<String, Object>> result = interpreter.query(employees, whereClause);
        
        // 输出结果
        System.out.println("Employees in IT department with salary > 55000:");
        for (Map<String, Object> emp : result) {
            System.out.println(emp);
        }
        
        // 另一个查询: age < 30 OR department = 'HR'
        SQLExpression young = new GreaterThanExpression("age", 25); // 注意:这里简化了,实际应该有小表达式
        SQLExpression inHR = new EqualsExpression("department", "HR");
        SQLExpression whereClause2 = new OrExpression(
            new NotExpression(new GreaterThanExpression("age", 29)), // age <= 29
            inHR
        );
        
        List<Map<String, Object>> result2 = interpreter.query(employees, whereClause2);
        System.out.println("\nEmployees age <= 29 OR in HR department:");
        for (Map<String, Object> emp : result2) {
            System.out.println(emp);
        }
    }
}
相关推荐
七月丶13 小时前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞13 小时前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼14 小时前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟1 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder1 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室2 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦2 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo6 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4966 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃6 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式