规则引擎

需求背景

在没有规则引擎的时代,有些逻辑比较复杂的业务,只有不断的增添 if-else 去满足我们这个复杂的业务场景。如果要增减策略,就得改代码上线,效率很差。

通过规则引擎,可以灵活配置规则,可以热更新。

低配版:没有配置界面,靠业务人员编写引擎规则DSL(比如 json 格式的),一般存储在数据库或者文件中,这种没有彻底解放业务人员和开发人员的耦合,但是加快了业务代码的上线速度,以及很容易就能进行规则变更。

进阶版:通过 WebUI 设置规则的组合

实现

基础思路如下:

type Rule struct {
    Condition func() bool // 条件,这里用了一个 bool型 的函数简化。实际应用中一般是一个条件字符串
    Action    func()      // 动作,符合条件的情况下需要执行的函数,一般为赋值语句
}

type RuleEngine struct {
    rules []*Rule
}

func NewRuleEngine() *RuleEngine {
    return &RuleEngine{}
}

func (re *RuleEngine) AddRule(rule *Rule) {
    re.rules = append(re.rules, rule)
}

func (re *RuleEngine) Run() {
    for _, rule := range re.rules {
        if rule.Condition() { // 如果满足条件
            rule.Action()     // 执行动作
        }
    }
}

这里的 ConditionAction 使用了函数,实际应用中多使用 json 来配置规则,需要更复杂的算法将文本类型的规则解析为 AST语法树,类似代码编译阶段,里面要写很多的 SWITCH CASE 语句判断操作符。

参考代码

Grule: https://github.com/hyperjumptech/grule-rule-engine/blob/master/docs/cn/RuleEngine_cn.md

Last updated