规则引擎的设计与实现 | 青训营笔记

311 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

规则引擎的设计与实现

目标

  • 理解规则引擎的组成部分及应用场景
  • 理解规则引擎的核心原理 -- 编译原理的相关概念
  • 设计并实现一个规则引擎 -- YoungEngine
  • 结合之前所学课程,实现一个web版规则引擎

认识规则引擎

引入例子

基本要求:抖音商城 购买商品会获得积分,然后不同区间有不同的积分计算

  1. 基本版本,不同区间不同积分,但区间数量不多,直接使用if else 判断

  2. 迭代版本1,不同区间不同积分,但是按照区间数额大小积分递增计算,此时区间数量很多,不好使用if else。此时做法其实还是类似枚举,只是说区间大小不应该写死在代码中,而是使用for range来遍历,通过设计对应的结构体,使得使用者能够通过创建结构体数组来确定对应的区间,例子:

    type reWardsRule struct{
      BeginPrice int 
      EndPrice int
      Points int
    }
    func ReWardsV2(price int, rules []reWardsRule) int {
      points := 0
      for _, rule := range rules {
        if price > rule.BeginPrice && price < rule.EndPoint {
          points = rule.Points
        }
      }
      return points
    }
    
  3. 迭代版本2,希望在前面版本的基础上,更加精细化,增加对于商品标签属性的信息,比如说新用户、特卖商品等,对应的积分会有不同变化。此时就更加复杂了,那么就引出了我们本次要看到的规则引擎,说白了我觉得其实是觉得中间这一层逻辑比较复杂了,所以包装出了一个新的中间层/组件来处理这个问题,也就是规则引擎。

定义

规则引擎是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

也就是说,让开发和业务分离。上面迭代版本1中间实际上也是分离的一种,但是对于不同需求的应对能力比较差。

解决开发人员重复编码的问题:业务决策与服务本身解耦,提高服务的可维护性缩短开发路径,提高效率。

组成部分

  • 数据输入

    支持接受使用预定义的语义编写的规则作为策略集。比如“price>500”

    (需要我们预先考虑好对应的策略和规则)

    接受业务的数据作为执行过程中的参数,比如价格、标签等

  • 规则理解

    能够按照预先定义的词法、语法、优先级、运算符等正确理解业务规则所表达的语义。

  • 规则执行

    根据执行时输入的参数对策略集中的规则进行正确的解释和执行。同时对规则执行过程中的数据类型进行检查,确保执行结果正确

应用场景:

  • 风控对抗

    与黑灰产进行对抗。规则引擎是风控系统的核心,通过对其不变调整和优化来进行对抗。(比如说来薅羊毛的)

  • 活动策略运营

    及时根据用户效果反馈进行运营策略的优化和调整

  • 数据分析和清洗

    可以快捷实现对数据的整理、清洗以及转换

编译原理基本概念

本科上过了,略

这里重点 把握一下编译原理的使用场景:

就是针对于一个具体的代码表达式,来获取具体的信息,比如说:

(这里price和isNewUser等都是内置的标识符)

p rice > 500 && ( isNewUser || userLevel > 5 )

通过词法分析进行识别和拆分,然后根据语法分析构建语法树,比对中间各种运算符的信息进行处理

中间会进行参数的类型检查,包括编译时检查和运行时检查等

  • 编译时检查:需要提前声明参数的类型,在构建语法树的过程中进行类型检查
  • 运行时检查:根据执行时的参数输入值类型,在执行过程中进行类型检查

规则引擎的实现

这里后面主要都是在解析代码了:www.cnblogs.com/kevinGaoblo…