规则引擎设计 | 青训营笔记

88 阅读4分钟

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

规则引擎设计与实现

今日学习:

  • 规则引擎
  • 编译原理的部分

课程重难点

重点

  • 规则引擎的设计 。明确设计目标、完成步骤拆解、完成各部分状态机的详细设计
  • 规则引擎的实现。基于项目工程完成词法分析、语法分析、抽象语法树的执行功能

难点

  • 规则引擎的核心原理(理论)。词法分析、语法分析、类型检查、语法树执行

    这些部分涉及到了数据结构

定义

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

解决开发人员重复编码的问题,提高维护性

组成部分

  • 数据输入

接受外界的数据输入,支持预定义的语法编写的规则。比如"price > 500",接受业务的数据作为执行过程中的参数

  • 规则理解

能够按照预先定义的语法,优先级等正确理解业务规则

  • 规则执行

根据执行时候输入的参数对策略集中的规则进行解释和执行。同时进行检查

应用

风控对抗

活动策略运营

数据分析

编译原理

image-20230131103052216

词法分析

把源代码字符串转化为词法单元的工程

price > 500 && (isNewUser || userLevel > 5) 

如何识别token?

有限自动机

有限自动机就是一个状态机,状态数量是有限的。该状态机在任何一个状态,基于输入的字符,都能做一个确定的状态转换

抽象语法树

image-20230131103855982

上下文无关语法

。。。。。
r:=a>b
.....
这是一个赋值语句,无论此语句的前后是什么代码,此语句所代表的操作是确定的。即给变量a赋值等于0

语法句子无需考虑上下文,可以判断正确性。可以使用巴斯克范式(BNF)来表达

BNF是描述上下文无关理论的一种具体方法,通过BNF可以实现上下文无关文法的具体化、公式化、科学化,是实现代码解析的必要条件。

exp:add; 
add:add `+` mul | mul ; // 加法表达式
mul: mul '*' pri | pri //乘法表达式
pri: string | bool | number | identifer;// 基础表达式

产生式:一个表达式可以由另外已知类型的表达式或者符号推导产生

内置符号:标识符,运算符

一个基础表达式可由 常量或标识符

一个乘法表达式可以由 基础表达式 获取乘法表达式*基础表达式 组成

递归下降算法

不断的对Token进行语法展开

示例

image-20230131105444152

过程就是从左到右不断遍历,然后根据找的词放在相应的位置,然后最后组装在一起

类型检查

类型综合

根据子表达式来构造父表达式的类型,例如,A+B的类型是根据A和B的类型定义的

编译时检查&运行时检查

类型检查可以在表达式的编译阶段,记载构造语法树的阶段;也可以发生在执行阶段

编译时:需要提前声明参数类型,在构造语法树的过程中进行类型检查

int 1: int ;str1:string

执行时:可以根据执行的参数输入的值类型,在执行过程中进行类型检查

int1: 108 ;str1:"22"

设计

目标

词法(合法token)

参数:字母数字下划线组成 eg:_ab2,user_name

布尔值:true,false

字符串:"22"

十进制int

十进制float

预定义运算符 +-

数据类型

字符串

布尔值

十进制int

十进制float

运算符

一元运算符 +-

二元

逻辑操作符

括号

优先级

image-20230131111539628

image-20230131111923474

常见的规则引擎

开源的代表是Drools,商业的代表是VisualRules ,iLog。

Java 开源的规则引擎有:Drools、URule、Easy Rules。使用最为广泛 Drools。

通过类型对规则引擎进行简单分类,一般有以下3类:

仓库

qimengxingyuan/young_engine: 简单的规则引擎 (github.com)

视频后期的演示仓库,容我拉下来好好看看,

代码感觉非常的规范但是有点复杂

个人理解

规则引擎就像一个系统,负责解析传入的规则,返回结果