解释器模式:给规则语言写一个解释器
业务规则、表达式计算、查询条件、模板语法,本质上都是“一门小语言”。解释器模式把语法规则翻译成可执行的对象树。
一、痛点:规则硬编码,变化起来很痛苦
一个风控系统需要判断:
(用户年龄大于 18)且(账户状态为正常)且(近 7 天登录次数大于 3)
如果直接把规则写成 Java 代码:
if (age > 18 && accountStatus.equals("NORMAL") && loginCount > 3) {
// 通过
}
规则一变,就要改代码、重新发布。业务人员也没法自己维护规则。
解释器模式的回答:把规则表达成可以被解析的表达式,再把表达式结构映射成对象树,通过递归求值得到结果。
二、实现:表达式接口 → 终结符/非终结符 → 解析求值
以最简单的布尔表达式为例,支持 true、false、and、or、not。
第一步:定义表达式接口
public interface Expression {
boolean interpret(Context context);
}
这里先简化,不需要 Context:
public interface Expression {
boolean evaluate();
}
第二步:终结符表达式
public class BooleanLiteral implements Expression {
private final boolean value;
public BooleanLiteral(boolean value) {
this.value = value;
}
@Override
public boolean evaluate() {
return value;
}
}
第三步:非终结符表达式
public class AndExpression implements Expression {
private final Expression left;
private final Expression right;
public AndExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public boolean evaluate() {
return left.evaluate() && right.evaluate();
}
}
public class OrExpression implements Expression {
private final Expression left;
private final Expression right;
public OrExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public boolean evaluate() {
return left.evaluate() || right.evaluate();
}
}
第四步:构造表达式树
Expression rule = new AndExpression(
new BooleanLiteral(true),
new OrExpression(
new BooleanLiteral(false),
new BooleanLiteral(true)
)
);
System.out.println(rule.evaluate()); // true
真实系统中,rule 不应由 Java 代码手动拼,而应由解析器把字符串规则转换为这棵表达式树。
三、真实落地需要更多组件
解释器模式的核心是“解释”,但生产级规则系统还要具备:
| 组件 | 作用 |
|---|---|
| 词法分析器 | 把字符串拆成 Token |
| 语法分析器 | 把 Token 构造成抽象语法树 |
| 上下文 | 保存变量、环境、中间结果 |
| 求值器 | 递归遍历语法树计算结果 |
像正则表达式、SQL、EL 表达式、规则引擎,底层都使用了类似思想。
四、适用边界与替代方案
解释器模式适合规则简单、语法稳定、变化频率可控的场景。如果规则非常复杂或频繁变化,直接使用成熟规则引擎(如 Drools)、表达式语言(SpEL、Aviator)通常更务实。
手写解释器要谨慎:它容易带来解析器维护成本、性能损耗和递归深度问题。
小结
解释器模式一句话:用对象树表示语法,用递归求值解释规则。它让“规则变化”从改 Java 代码走向改表达式,适合小而稳定的领域语言。

954

被折叠的 条评论
为什么被折叠?



