设计模式(解释器模式(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);
        }
    }
}
相关推荐
猫头虎5 小时前
OpenAI发布构建AI智能体的实践指南:实用框架、设计模式与最佳实践解析
人工智能·设计模式·开源·aigc·交互·pip·ai-native
昨天的猫6 小时前
项目中原来策略模式这么玩才有意思😁😁😁
设计模式
Mr_WangAndy6 小时前
C++设计模式_行为型模式_迭代器模式Iterator
c++·设计模式·迭代器模式
白衣鸽子6 小时前
【基础数据篇】数据遍历大师:Iterator模式
后端·设计模式
muxin-始终如一6 小时前
系统重构过程以及具体方法
设计模式·重构
Mr_WangAndy19 小时前
C++设计模式_行为型模式_责任链模式Chain of Responsibility
c++·设计模式·责任链模式·行为型模式
星空寻流年19 小时前
设计模式第七章(责任链模式)
设计模式·责任链模式
Deschen19 小时前
设计模式-原型模式
java·设计模式·原型模式
☆cwlulu19 小时前
c++最常用的几种设计模式
设计模式