设计模式18-解释器模式:小语言的语法解析

解释器模式:给规则语言写一个解释器

业务规则、表达式计算、查询条件、模板语法,本质上都是“一门小语言”。解释器模式把语法规则翻译成可执行的对象树。

一、痛点:规则硬编码,变化起来很痛苦

一个风控系统需要判断:

(用户年龄大于 18)且(账户状态为正常)且(近 7 天登录次数大于 3)

如果直接把规则写成 Java 代码:

if (age > 18 && accountStatus.equals("NORMAL") && loginCount > 3) {
    // 通过
}

规则一变,就要改代码、重新发布。业务人员也没法自己维护规则。

解释器模式的回答:把规则表达成可以被解析的表达式,再把表达式结构映射成对象树,通过递归求值得到结果

二、实现:表达式接口 → 终结符/非终结符 → 解析求值

以最简单的布尔表达式为例,支持 truefalseandornot

第一步:定义表达式接口

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 代码走向改表达式,适合小而稳定的领域语言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值