一、解释器模式核心定义
解释器模式是行为型设计模式的一种,核心目的是:
定义一个语言的文法(语法规则),并构建一个解释器来解释该语言中的句子(表达式)。简单来说,就是自定义一套 "小语言 / 规则",并写代码来解析执行这套规则。
核心解决的问题
- 自定义规则解析:当系统需要处理固定格式的规则 / 表达式(如数学公式、权限规则、过滤条件)时,用解释器模式将规则拆解为可执行的 "语法单元";
- 规则复用与扩展:相同类型的规则可通过组合语法单元实现复用,新增规则只需新增语法单元(而非重构整个解析逻辑)。
生活类比(快速理解)
- 场景 1 :计算器计算 1 + 2 * 3
- 文法(规则):四则运算规则(先乘除后加减);
- 解释器:计算器程序(拆解表达式为 "数字""+""*" 等单元,按规则计算);
- 句子:1 + 2 * 3(需要解析执行的表达式)。
- 场景 2 :快递运费规则 重量>10kg 且 距离>500km → 运费=重量2 + 距离0.1
- 文法:逻辑判断(>)、算术运算(*+)、条件分支;
- 解释器:运费计算程序(解析规则并执行);
- 句子:具体的运费规则表达式。
角色
| 角色 | 职责 | 类比(计算器场景) |
|---|---|---|
| 抽象表达式(AbstractExpression) | 定义解释器的统一接口(核心:interpret()方法) |
运算规则接口(规定 "计算" 行为) |
| 终结符表达式(TerminalExpression) | 文法中的最小单元(不可再拆分),如数字、常量、基础运算符 | 数字(1/2/3)、变量(x/y) |
| 非终结符表达式(NonTerminalExpression) | 文法中的复合单元(由多个表达式组合而成),如加减乘除、逻辑运算 | 加法(+)、乘法(*) |
| 上下文(Context) | 存储解释器的全局状态(如变量值、计算结果),供所有表达式共享 | 存储数字值、运算中间结果 |
| 客户端(Client) | 构建表达式树(组合终结符 / 非终结符),调用解释器执行 | 用户输入表达式,触发计算 |
核心 UML 类图

二、基础版实现(四则运算解释器)
以 "支持加减乘除的简单计算器" 为例,实现解释器模式的核心逻辑 ------ 这是解释器模式最经典的入门案例。
1. 步骤 1:定义上下文(存储变量 / 结果)
import java.util.HashMap;
import java.util.Map;
/**
* 上下文:存储表达式中的变量值和计算状态
*/
public class CalculatorContext {
// 变量名 → 值(如 "a" → 10, "b" → 20)
private final 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);
}
}
2. 步骤 2:定义抽象表达式
/**
* 抽象表达式:四则运算表达式的统一接口
*/
public abstract class AbstractExpression {
/**
* 解释表达式并返回计算结果
* @param context 上下文(存储变量值)
* @return 计算结果
*/
public abstract int interpret(CalculatorContext context);
}
3. 步骤 3:实现终结符表达式(数字 / 变量)
/**
* 终结符表达式:变量表达式(如 a、b、x)
* 最小语法单元,不可再拆分
*/
public class VariableExpression extends AbstractExpression {
private final String variableName; // 变量名(如 "a")
public VariableExpression(String variableName) {
this.variableName = variableName;
}
@Override
public int interpret(CalculatorContext context) {
// 直接从上下文获取变量值(核心:终结符仅读取/返回值,无计算)
return context.getVariable(variableName);
}
}
4. 步骤 4:实现非终结符表达式(加减乘除)
/**
* 非终结符表达式:加法表达式(由两个子表达式组成)
*/
public class AddExpression extends AbstractExpression {
private final AbstractExpression left; // 左表达式
private final AbstractExpression right; // 右表达式
public AddExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(CalculatorContext context) {
// 先解释左、右表达式,再执行加法(核心:非终结符组合子表达式计算)
return left.interpret(context) + right.interpret(context);
}
}
/**
* 非终结符表达式:乘法表达式
*/
public class MultiplyExpression extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public MultiplyExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(CalculatorContext context) {
return left.interpret(context) * right.interpret(context);
}
}
5. 步骤 5:客户端(构建表达式树并执行)
/**
* 客户端:构建四则运算表达式树,执行解释计算
* 示例:计算 a + b * c (a=1, b=2, c=3 → 1+2*3=7)
*/
public class InterpreterClient {
public static void main(String[] args) {
// 1. 创建上下文,设置变量值
CalculatorContext context = new CalculatorContext();
context.setVariable("a", 1);
context.setVariable("b", 2);
context.setVariable("c", 3);
// 2. 构建表达式树:a + (b * c)
// 终结符:a、b、c
AbstractExpression a = new VariableExpression("a");
AbstractExpression b = new VariableExpression("b");
AbstractExpression c = new VariableExpression("c");
// 非终结符:b * c
AbstractExpression multiply = new MultiplyExpression(b, c);
// 非终结符:a + (b * c)
AbstractExpression add = new AddExpression(a, multiply);
// 3. 解释执行表达式
int result = add.interpret(context);
System.out.println("表达式 a + b * c 的计算结果:" + result); // 输出 7
// 扩展:修改变量值,重新计算(无需修改表达式树)
context.setVariable("a", 10);
int result2 = add.interpret(context);
System.out.println("修改a=10后,计算结果:" + result2); // 输出 16
}
}
输出结果
表达式 a + b * c 的计算结果:7
修改a=10后,计算结果:16
三、Spring 实战版(权限规则解释器)
在业务开发中,解释器模式最常见的场景是权限规则解析、动态过滤条件解析 。以下实现一个 "用户权限规则解释器",支持解析如 role=ADMIN 且 dept=IT 或 level>5 的规则。
1. 依赖准备(Spring Boot)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.2.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2. 核心模型定义
import lombok.Data;
/**
* 用户信息(上下文数据)
*/
@Data
public class User {
private String userId;
private String role; // 角色:ADMIN/USER/GUEST
private String dept; // 部门:IT/HR/Finance
private int level; // 等级:1-10
}
/**
* 权限上下文:存储用户信息和规则解析状态
*/
@Data
public class PermissionContext {
private User user; // 当前用户
private boolean result; // 解析结果(是否有权限)
}
3. 抽象表达式(权限规则)
/**
* 抽象表达式:权限规则表达式
*/
public abstract class AbstractPermissionExpression {
/**
* 解释权限规则
* @param context 权限上下文
* @return 是否满足规则
*/
public abstract boolean interpret(PermissionContext context);
}
4. 终结符表达式(基础规则)
/**
* 终结符表达式:角色匹配规则(如 role=ADMIN)
*/
public class RoleExpression extends AbstractPermissionExpression {
private final String targetRole; // 目标角色
public RoleExpression(String targetRole) {
this.targetRole = targetRole;
}
@Override
public boolean interpret(PermissionContext context) {
// 核心:匹配用户角色
return targetRole.equals(context.getUser().getRole());
}
}
/**
* 终结符表达式:部门匹配规则(如 dept=IT)
*/
public class DeptExpression extends AbstractPermissionExpression {
private final String targetDept; // 目标部门
public DeptExpression(String targetDept) {
this.targetDept = targetDept;
}
@Override
public boolean interpret(PermissionContext context) {
return targetDept.equals(context.getUser().getDept());
}
}
/**
* 终结符表达式:等级大于规则(如 level>5)
*/
public class LevelGtExpression extends AbstractPermissionExpression {
private final int targetLevel; // 目标等级
public LevelGtExpression(int targetLevel) {
this.targetLevel = targetLevel;
}
@Override
public boolean interpret(PermissionContext context) {
return context.getUser().getLevel() > targetLevel;
}
}
5. 非终结符表达式(逻辑组合)
/**
* 非终结符表达式:逻辑与(AND)
*/
public class AndExpression extends AbstractPermissionExpression {
private final AbstractPermissionExpression left;
private final AbstractPermissionExpression right;
public AndExpression(AbstractPermissionExpression left, AbstractPermissionExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(PermissionContext context) {
// 左、右表达式都满足才返回true
return left.interpret(context) && right.interpret(context);
}
}
/**
* 非终结符表达式:逻辑或(OR)
*/
public class OrExpression extends AbstractPermissionExpression {
private final AbstractPermissionExpression left;
private final AbstractPermissionExpression right;
public OrExpression(AbstractPermissionExpression left, AbstractPermissionExpression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(PermissionContext context) {
// 左、右表达式有一个满足就返回true
return left.interpret(context) || right.interpret(context);
}
}
6. 解释器管理器(Spring Bean)
import org.springframework.stereotype.Component;
/**
* 权限规则解释器管理器(统一解析入口)
*/
@Component
public class PermissionInterpreterManager {
/**
* 解析权限规则:role=ADMIN 且 dept=IT 或 level>5
*/
public boolean checkPermission(User user) {
// 1. 创建上下文
PermissionContext context = new PermissionContext();
context.setUser(user);
// 2. 构建规则表达式树:(role=ADMIN AND dept=IT) OR level>5
AbstractPermissionExpression adminRole = new RoleExpression("ADMIN");
AbstractPermissionExpression itDept = new DeptExpression("IT");
AbstractPermissionExpression andExpr = new AndExpression(adminRole, itDept);
AbstractPermissionExpression levelGt5 = new LevelGtExpression(5);
AbstractPermissionExpression orExpr = new OrExpression(andExpr, levelGt5);
// 3. 解释执行规则
return orExpr.interpret(context);
}
}
7. 客户端(Spring Boot 测试)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringInterpreterDemoApplication {
public static void main(String[] args) {
// 1. 启动Spring容器
ConfigurableApplicationContext context = SpringApplication.run(SpringInterpreterDemoApplication.class, args);
PermissionInterpreterManager interpreterManager = context.getBean(PermissionInterpreterManager.class);
// 2. 测试用户1:ADMIN + IT部门 → 满足规则
User user1 = new User();
user1.setUserId("U001");
user1.setRole("ADMIN");
user1.setDept("IT");
user1.setLevel(3);
boolean result1 = interpreterManager.checkPermission(user1);
System.out.println("用户1是否有权限:" + result1); // true
// 3. 测试用户2:USER + HR部门 + level=6 → 满足规则(level>5)
User user2 = new User();
user2.setUserId("U002");
user2.setRole("USER");
user2.setDept("HR");
user2.setLevel(6);
boolean result2 = interpreterManager.checkPermission(user2);
System.out.println("用户2是否有权限:" + result2); // true
// 4. 测试用户3:USER + Finance部门 + level=4 → 不满足规则
User user3 = new User();
user3.setUserId("U003");
user3.setRole("USER");
user3.setDept("Finance");
user3.setLevel(4);
boolean result3 = interpreterManager.checkPermission(user3);
System.out.println("用户3是否有权限:" + result3); // false
context.close();
}
}
输出结果
用户1是否有权限:true
用户2是否有权限:true
用户3是否有权限:false
四、解释器模式的核心特点与适用场景
优点
- 规则可扩展 :新增规则只需新增表达式类(如新增
level<3规则,只需加LevelLtExpression),符合开闭原则;- 规则可复用 :相同的基础规则(如
role=ADMIN)可组合到不同的复杂规则中;- 规则结构化:将复杂规则拆解为小的语法单元,便于理解和维护;
- 动态执行:可通过上下文动态修改参数(如用户信息),无需重新构建表达式树。
缺点
- 类膨胀:每个语法单元都需创建独立类,复杂规则会导致类数量爆炸;
- 效率低下:表达式树嵌套越深,解释执行的效率越低(递归调用 + 多次上下文访问);
- 仅适用于简单文法:复杂文法(如 SQL、正则表达式)不适合用解释器模式(应使用现成的解析器工具);
- 调试复杂:表达式树的递归执行流程难以跟踪和调试。
适用场景
- 简单规则解析:如权限规则、过滤条件、动态配置(非复杂文法);
- 领域特定语言(DSL):如自定义的业务规则语言(如运费计算规则、促销规则);
- 重复执行的固定格式表达式:如计算器、公式解析器、简单的规则引擎;
- 框架底层扩展:如 Spring EL、OGNL、MyBatis 的动态 SQL 解析(框架级应用)。
五、框架中的原生应用(必须知道)
解释器模式主要用于框架底层,业务开发中很少直接手写,但理解它能帮你看懂框架源码:
1. Spring EL(表达式语言)
- 文法:Spring EL 的语法规则(如
${user.name}、#{1+2*3}); - 抽象表达式:
Expression接口; - 终结符 / 非终结符:
LiteralExpression(字面量)、OpPlus(加法)等; - 解释器:
SpelExpression(核心解释执行类)。
2. MyBatis 动态 SQL
- 文法:动态 SQL 的标签规则(
<if>、<where>、<foreach>); - 解释器:MyBatis 的
SqlSource和DynamicSqlSource(解析动态标签,生成最终 SQL)。
3. Java 正则表达式(Pattern/Matcher)
- 文法:正则表达式的语法规则;
- 解释器:
Pattern(编译正则表达式为语法树)、Matcher(解释执行匹配逻辑)。
4. 计算器 / 公式引擎(如 JEP、MVEL)
- 核心:基于解释器模式实现数学公式的解析和计算。
六、解释器模式 vs 策略模式(易混淆点)
| 维度 | 解释器模式 | 策略模式 |
|---|---|---|
| 核心目的 | 解析并执行固定格式的规则 / 表达式 | 选择并执行不同的算法 / 方案 |
| 核心结构 | 表达式树(终结符 + 非终结符组合) | 策略接口 + 多个实现类 |
| 扩展方式 | 新增表达式类(扩展语法单元) | 新增策略类(扩展算法) |
| 执行逻辑 | 递归解析表达式树 | 直接调用策略方法 |
| 典型场景 | 规则解析、公式计算、DSL | 支付方式选择、排序算法、缓存策略 |
总结
- 解释器模式的核心是定义文法规则,将表达式拆解为可执行的语法单元,适用于简单规则 / 表达式的解析执行;
- 核心角色包括抽象表达式、终结符表达式(最小单元)、非终结符表达式(组合单元)、上下文(存储状态);
- 业务开发中,解释器模式主要用于权限规则、过滤条件等简单场景,复杂文法应使用现成的解析器工具(如 ANTLR、Spring EL);
- 解释器模式的优点是规则可扩展、可复用,缺点是类膨胀、效率低,仅适用于简单场景。
