当前位置: 首页 > article >正文

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 数学表达式解析器

// 上下文(存储变量值)
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 支持优先级运算

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. 使用组合模式构建语法树
abstract class BinaryExpression implements MathExpression {
    protected MathExpression left;
    protected MathExpression right;
    
    public BinaryExpression(MathExpression left, MathExpression right) {
        this.left = left;
        this.right = right;
    }
}
  1. 结合工厂模式创建表达式
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. 实现上下文缓存优化
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. 使用访问者模式实现多种操作
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条件解析)

// 条件表达式接口
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)的场景。该模式在规则引擎、查询语言解析和公式计算等领域应用广泛,是处理语法解析问题的经典解决方案。


http://www.kler.cn/a/565917.html

相关文章:

  • 动态规划 之 枚举型
  • Oracle 数据库基础入门(二):深入理解表的约束
  • [STM32]从零开始的STM32 DEBUG问题讲解及解决办法
  • 对比Grok3 普通账户与 30 美元 Super 账户:默认模式、Think 和 DeepSearch 次数限制以及如何升级
  • python-leetcode-删除并获得点数
  • CAS (Compare and swap “比较和交换“) [ Java EE 初阶 ]
  • 【Java基础】Java中new一个对象时,JVM到底做了什么?
  • 分布式系统中的关键技术解析:幂等性、负载均衡、限流算法及其实现
  • 做表格用什么软件?VeryReport让数据管理更高效!
  • 1.14 重叠因子:TRIMA三角移动平均线(Triangular Moving Average, TRIMA)概念与Python实战
  • 利用 Python 爬虫进行跨境电商数据采集
  • 1-8 gdb调试
  • 齿轮制造的“精密心脏”:蜗杆状砂轮磨齿机探秘
  • 回溯算法中的for循环和递归使用
  • Linux基础33-C语言篇之字符串的基础操作【入门级】
  • StableDiffusion打包 项目迁移 项目分发 1
  • vue el-table-column 单元表格的 省略号 实现
  • P1706 全排列问题
  • 使用python做http代理请求
  • docker和containerd从TLS harbor拉取镜像