用对象树表示一门小语言
解释器模式把一条规则或一门小语言的语法表示成对象树:每个节点实现同一个解释方法,组合出与、或、非、比较等结构,由上下文提供变量取值。它适合简单、稳定、变化少的小语言,例如规则引擎里的判定表达式;语法一旦复杂起来,手写解释器的维护成本会迅速超过收益。
基本信息
| 意图 | 用对象结构表示语法并解释执行 |
|---|---|
| 适用 | 简单、稳定、变更少的小语言或规则集 |
| 结构 | 抽象表达式、终结符与非终结符节点、上下文 |
| 边界 | 复杂语法改用解析器生成器或现成表达式引擎 |
典型使用场景
- 规则引擎:会员等级、金额阈值、黑名单等组合判定
- 查询条件:把界面上的筛选条件转成可解释的表达式树
- 权限判定:角色、资源、动作三元组的组合规则
- 简单计算语言:单位换算、公式求值
- 告警规则:设备状态与阈值的组合触发条件
结构示意
结构示意
# 规则文本先解析成表达式树,再由各节点解释执行
rule = And(
Or(Equals('tier', 'vip'), GreaterThan('amount', 1000)),
Not(Variable('blacklist')),
)
result = rule.interpret(ctx)
# 终结符节点:直接取上下文里的变量做比较
# 非终结符节点:递归求子节点结果,与或非需实现短路求值结构要素与职责
| 要素 | 职责 | 常见问题 |
|---|---|---|
| 抽象表达式 | 声明解释方法 | 接口过宽,把解析也塞进来 |
| 终结符节点 | 直接求值,如变量与常量 | 变量名写错只有运行期才暴露 |
| 非终结符节点 | 递归组合子节点结果 | 未实现短路求值,性能被拖累 |
| 上下文 | 提供变量与运行状态 | 上下文变成全局变量袋,谁都能改 |
语法树要能序列化与校验:规则常需要持久化、版本化与灰度发布,因此节点类型要保持稳定,最好配套一个「文本转树」的解析与合法性校验,而不是只在代码里手搭对象。
演进路径:规则只有三五个时手写解释器够用;规则由业务方频繁配置、需要可视化编辑时,引入现成表达式引擎或解析器生成器,把精力放在语义与安全边界上。