java23种设计模式-解释器模式

解释器模式(Interpreter Pattern)学习笔记


编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793

DeepSeek使用技巧pdf资料分享:https://blog.csdn.net/weixin_47763579/article/details/145884039


1. 模式定义

行为型设计模式,给定一个语言,定义其文法的一种表示,并定义一个解释器,用于解释语言中的句子。通过构建语法树来实现特定领域语言的解释执行。

2. 适用场景

✅ 需要解释执行特定领域语言

✅ 文法规则相对稳定且易于扩展

✅ 需要频繁解释简单语法结构

✅ 不追求高效执行效率的场景

✅ 实现SQL解析、正则表达式引擎等

3. 模式结构

contains <<interface>> AbstractExpression +interpret(context: Context) : Object TerminalExpression +interpret(context: Context) : Object NonterminalExpression -expressions: List +interpret(context: Context) : Object Context -variables: Map +getVariable(name: String) : Object +setVariable(name: String, value: Object) Client +buildExpressionTree() : AbstractExpression

4. 核心角色

角色 说明
AbstractExpression 抽象表达式:声明解释操作的接口
TerminalExpression 终结符表达式:实现与文法中的终结符相关的解释操作
NonterminalExpression 非终结符表达式:维护包含其他表达式的结构,实现文法规则的组合解释逻辑
Context 上下文:包含解释器需要的全局信息
Client 客户端:构建语法树并调用解释方法

5. 代码示例

5.1 数学表达式解析器

java 复制代码
// 上下文(存储变量值)
class MathContext {
    private Map<String, Integer> variables = new HashMap<>();
    
    public void setVariable(String name, int value) {
        variables.put(name, value);
    }
    
    public int getVariable(String name) {
        return variables.getOrDefault(name, 0);
    }
}

// 抽象表达式
interface MathExpression {
    int interpret(MathContext context);
}

// 终结符表达式 - 数字
class Number implements MathExpression {
    private int number;
    
    public Number(int number) {
        this.number = number;
    }
    
    public int interpret(MathContext context) {
        return number;
    }
}

// 终结符表达式 - 变量
class Variable implements MathExpression {
    private String name;
    
    public Variable(String name) {
        this.name = name;
    }
    
    public int interpret(MathContext context) {
        return context.getVariable(name);
    }
}

// 非终结符表达式 - 加法
class Add implements MathExpression {
    private MathExpression left;
    private MathExpression right;
    
    public Add(MathExpression left, MathExpression right) {
        this.left = left;
        this.right = right;
    }
    
    public int interpret(MathContext context) {
        return left.interpret(context) + right.interpret(context);
    }
}

// 非终结符表达式 - 减法
class Subtract implements MathExpression {
    private MathExpression left;
    private MathExpression right;
    
    public Subtract(MathExpression left, MathExpression right) {
        this.left = left;
        this.right = right;
    }
    
    public int interpret(MathContext context) {
        return left.interpret(context) - right.interpret(context);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        // 构建表达式:a + (b - 10)
        MathContext context = new MathContext();
        context.setVariable("a", 20);
        context.setVariable("b", 30);
        
        MathExpression expression = new Add(
            new Variable("a"),
            new Subtract(
                new Variable("b"),
                new Number(10)
            )
        );
        
        int result = expression.interpret(context);
        System.out.println("计算结果: " + result); // 输出:20 + (30-10) = 40
    }
}

6. 模式变种

6.1 支持优先级运算

java 复制代码
class Multiply extends BinaryExpression {
    public Multiply(MathExpression left, MathExpression right) {
        super(left, right);
    }
    
    public int interpret(MathContext context) {
        return left.interpret(context) * right.interpret(context);
    }
}

class Power extends BinaryExpression {
    public Power(MathExpression left, MathExpression right) {
        super(left, right);
    }
    
    public int interpret(MathContext context) {
        return (int) Math.pow(
            left.interpret(context),
            right.interpret(context)
        );
    }
}

7. 优缺点分析

✔️ 优点

  • 易于扩展新的文法规则
  • 实现语言解释器的标准模式
  • 将语法解析与表达式求值分离
  • 符合单一职责原则

缺点

  • 复杂文法难以维护(类数量爆炸)
  • 执行效率较低(递归调用多)
  • 应用场景有限
  • 难以处理左递归文法

8. 相关模式对比

模式 目的 关键区别
组合模式 树形结构处理 解释器通常使用组合模式构建语法树
访问者模式 分离数据结构与操作 解释器模式侧重语法解析,访问者侧重数据操作
策略模式 封装算法族 解释器模式处理语言解析,策略处理算法选择

9. 实际应用案例

  • Java正则表达式引擎(Pattern/Matcher)
  • Spring表达式语言(SpEL)
  • SQL解析器实现
  • 金融领域的业务规则引擎
  • 编译器语法分析阶段
  • XML文档解析器
  • 数学公式计算器

10. 最佳实践建议

  1. 使用组合模式构建语法树
java 复制代码
abstract class BinaryExpression implements MathExpression {
    protected MathExpression left;
    protected MathExpression right;
    
    public BinaryExpression(MathExpression left, MathExpression right) {
        this.left = left;
        this.right = right;
    }
}
  1. 结合工厂模式创建表达式
java 复制代码
class ExpressionFactory {
    public static MathExpression create(String expr) {
        // 解析表达式字符串,构建语法树
        // 示例:解析 "a + b * 3"
        return new Add(
            new Variable("a"),
            new Multiply(
                new Variable("b"),
                new Number(3)
            )
        );
    }
}
  1. 实现上下文缓存优化
java 复制代码
class CachedExpression implements MathExpression {
    private MathExpression expression;
    private Map<MathContext, Integer> cache = new WeakHashMap<>();
    
    public CachedExpression(MathExpression expression) {
        this.expression = expression;
    }
    
    public int interpret(MathContext context) {
        return cache.computeIfAbsent(context, 
            ctx -> expression.interpret(ctx));
    }
}
  1. 使用访问者模式实现多种操作
java 复制代码
interface ExpressionVisitor {
    void visit(Number number);
    void visit(Variable variable);
    void visit(Add add);
    void visit(Subtract subtract);
}

class PrintVisitor implements ExpressionVisitor {
    public void visit(Number number) {
        System.out.print(number.value);
    }
    
    public void visit(Variable variable) {
        System.out.print(variable.name);
    }
    
    public void visit(Add add) {
        add.left.accept(this);
        System.out.print(" + ");
        add.right.accept(this);
    }
    // 其他visit方法...
}

📜 设计原则体现

  1. 单一职责原则:每个表达式类只处理特定语法元素
  2. 开闭原则:新增表达式类型无需修改现有代码
  3. 组合优于继承:通过组合方式构建复杂表达式

11. 扩展应用(SQL条件解析)

java 复制代码
// 条件表达式接口
interface Condition {
    boolean interpret(Map<String, Object> row);
}

// 等于条件
class Equals implements Condition {
    private String column;
    private Object value;
    
    public Equals(String column, Object value) {
        this.column = column;
        this.value = value;
    }
    
    public boolean interpret(Map<String, Object> row) {
        return value.equals(row.get(column));
    }
}

// AND条件
class And implements Condition {
    private Condition left;
    private Condition right;
    
    public And(Condition left, Condition right) {
        this.left = left;
        this.right = right;
    }
    
    public boolean interpret(Map<String, Object> row) {
        return left.interpret(row) && right.interpret(row);
    }
}

// 使用示例
Condition condition = new And(
    new Equals("status", "active"),
    new Or(
        new Equals("age", 25),
        new GreaterThan("score", 80)
    )
);

Map<String, Object> row = new HashMap<>();
row.put("status", "active");
row.put("age", 26);
row.put("score", 85);

boolean result = condition.interpret(row); // 返回true

通过解释器模式,可以实现灵活的语言解释功能,特别适合需要自定义领域特定语言(DSL)的场景。该模式在规则引擎、查询语言解析和公式计算等领域应用广泛,是处理语法解析问题的经典解决方案。

相关推荐
麗o麗1 分钟前
C语言整体梳理-基础篇-预处理指令
java·c语言·前端
非 白10 分钟前
【Java】Tomcat日志
java·开发语言·tomcat
Dyan_csdn25 分钟前
【Java项目】基于SpringBoot的【旅游管理系统】
java·spring·tomcat
猿周LV39 分钟前
CAS (Compare and swap “比较和交换“) [ Java EE 初阶 ]
java·java-ee
Lojarro41 分钟前
JavaEE基础之-请求对象request与响应对象response
java·java-ee
逸风尊者1 小时前
开发易忽视的问题:Java对象只能分配到堆上嘛
java·后端·面试
虾球xz1 小时前
游戏引擎学习第127天
java·学习·游戏引擎
钰云空间1 小时前
MAVEN的安装和配置指南【超详细】
java·maven
楠枬1 小时前
在线抽奖系统——项目测试
java·spring boot·功能测试·spring
m0_748238781 小时前
Spring Boot(快速上手)
java·spring boot·后端