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

server/2025/3/3 13:48:30/

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


http://www.ppmy.cn/server/172084.html

相关文章

Asp.Net Web API| React.js| EF框架 | SQLite|

asp.net web api EF SQLiteReact前端框架 设计一个首页面&#xff0c;包含三个按钮分别对应三类用户&#xff08;数据查看&#xff0c;设计人员&#xff0c;管理员&#xff09;&#xff0c;当点击管理员的时候弹出一个前端页面可以输入信息&#xff08;以学生数据为例&#…

CSS定位详解

1. 相对定位 1.1 如何设置相对定位&#xff1f; 给元素设置 position:relative 即可实现相对定位。 可以使用 left 、 right 、 top 、 bottom 四个属性调整位置。 1.2 相对定位的参考点在哪里&#xff1f; 相对自己原来的位置 1.3 相对定位的特点&#xff1…

MCAL-I/O驱动

I/O驱动由PORT驱动、DIO驱动、ADC驱动、PWM驱动、ICU驱动、OCU驱动六部分组成。 1. PORT驱动 功能概述: PORT 驱动初始化是对微控制器的整个 PORT 模块进行初始化配置。它负责配置端口和管脚的功能,如通用 I/O、模数转换、脉宽调制等。 实现方法: 初始化端口引脚。设置引…

Docker--Docker 镜像制作

镜像制作的原因 镜像制作是因为官方镜像无法满足自身需求&#xff0c;从而需要自己制作&#xff0c;我们需要通过条件来进行满足需求&#xff1b; 在软件开发过程中&#xff0c;开发环境和生产环境的差异可能导致“在我的机器上可以运行”的问题。Docker镜像将应用程序及其依…

SheetDataMerge合并工作表(excel)内多行同类数据的小工具。

SheetDataMerge SheetDataMerge是一款简单易用的工具&#xff0c;能够快速合并工作表中的多行同类数据。虽然Excel自带的数据透视表也能实现类似功能&#xff0c;但它属于进阶操作&#xff0c;需要一定的学习成本。 相比之下&#xff0c;SheetDataMerge的操作非常便捷&#xff…

DHCP配置实验

实验拓扑图 首先配置server的IP地址和网关 接下来配置R1 undo info-center enable dhcp enable //开启DHCP服务 ip pool dhcp-pool1 //开始配置dhcp地址池 gateway-list 192.168.1.254 //配置网关 network 192.168.1.0 mask 255.255.255.0 //配置网段和子网掩码 dns-list …

MySQL,Oracle,MariaDB的区别

MySQL、Oracle 和 MariaDB 都是流行的关系型数据库管理系统&#xff0c;它们各有特点&#xff0c;适用于不同的应用场景。以下是它们之间的主要区别&#xff1a; 1. MySQL 开发者&#xff1a;最初由 MySQL AB 开发&#xff0c;后来被 Oracle 公司收购。许可证&#xff1a;开源…

【AI+智造】在阿里云Ubuntu 24.04上部署DeepSeek R1 14B的完整方案

作者&#xff1a;Odoo技术开发/资深信息化负责人 日期&#xff1a;2025年2月28日 一、部署背景与目标 DeepSeek R1作为国产大语言模型的代表&#xff0c;凭借其强化学习驱动的推理能力&#xff0c;在复杂任务&#xff08;如数学问题、编程逻辑&#xff09;中表现优异。本地化部…