自定义协议实现aviator脚本生成

本文介绍了一种自定义协议,用于在业务规则引擎配置系统中,与前端约定规则渲染方式,并通过这套协议生成aviator脚本。协议涉及Rule、ConditionExpression和OutputExpression的定义,以及表达式因子、操作运算符和值对象。文章还概述了如何根据这些对象实现规则解析和编译成可执行脚本。
摘要由CSDN通过智能技术生成

前言

实现业务规则引擎配置系统,需要开发便于用户理解和使用的规则配置页面,为此需要与前端约定一套协议,用于规则的渲染,同时后端基于这套协议编译生成可执行的aviator脚本表达式。

前端视图示意

略。

数据协议定义

业务用户以规则为基本单位进行业务规则配置,从研发视角看,将业务规则抽象为Rule,一条Rule规则由条件部分的表达式对象ConditionExpression和输出部分的表达式对象OutputExpression组成。

ConditionExpression对象实质上是一个逻辑表达式,且支持多个逻辑表达式片段组合而成,并且最终运行结果是一个boolean值,如果运行结果为true,才会执行输出部分的表达式。

OutputExpression输出表达式部分则是由一个或多个赋值语句组成。

ConditionExpression和OutputExpression都可以抽象为由表达式片段Expression组成,不同的是条件部分的表达式可以通过连接逻辑运算法进行嵌套组合,而OutputExpression是一个或多个独立的赋值表达式组成。

最基本的表达式片段Expression由表达式因子、操作运算符、值对象三部分组成,考虑到多元运算符、表达式嵌套等情形,可以在Expression中增加连接操作符、嵌套定义下一个表达式片段。

表达式因子可以看做是表达式中的变量(或是条件),其对应开放给业务配置规则时使用的业务条件。

操作符包含几大类:

  1. 逻辑运算符且、或、非
  2. 原始的算数运算符加、减、乘、除
  3. 关系运算符(比较运算符)大于、小于、大于等于、小于等于
  4. 自定义实现的扩展运算符

值对象主要用于描述用户配置的值,该值可以是常量,也可以是变量,从其他第三方数据来源获取和输入。

基于以上对象,可以进一步组合丰富业务规则的管理。

+  规则领域集合

    -   规则领域集合元信息
    +  规则场景组
        -   规则场景组元信息
        +  规则
            -   规则元信息
            +  规则条件 (递归嵌套定义)
                -  表达式因子
                -  操作符
                -  值对象
                -  逻辑连接符
            +  规则输出部分(数组)
                -  表达式因子
                -  操作符
                -  值对象

代码实现

(以下仅表达主要思路,忽略其他个性化的业务处理逻辑)

  • 数据类型 DataTypeEnum
package com.xxx.rules.engine.enums;

public enum DataTypeEnum {

    Boolean,
    BigDecimal,
    String,
    Object,
    Array,
    Variable,
    Null;

}
  • 操作符类型 OperatorTypeEnum 
package com.xxx.rules.engine.enums;

public enum OperatorTypeEnum {

    NATIVE_LOGICAL("logical"), //逻辑操作符
    NATIVE_ARITHMETIC("arithmetic"), //算数运算法
    NATIVE_RELATIONSHIP("relationship"), //关系操作符
    CUSTOM("custom"); //自定义操作符

    /**
     * 操作符类型
     */
    private String type;

    OperatorTypeEnum(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}
  • 操作符 Operator
package com.xxx.rules.engine.domain;

import com.xxx.rules.engine.enums.OperatorTypeEnum;
import lombok.Getter;

/**
 * 操作符,包括逻辑操作符:且、或、非;运算操作符加减乘除;自定义运算法包含、不包含等等
 */
@Getter
public class Operator {

    public static Operator AND = new Operator("&&", "并且", OperatorTypeEnum.NATIVE_LOGICAL);
    public static Operator OR = new Operator("||", "或者", OperatorTypeEnum.NATIVE_LOGICAL);
    public static Operator NOT = new Operator("!", "非", OperatorTypeEnum.NATIVE_LOGICAL);

    public static Operator ADD = new Operator("+", "加上", OperatorTypeEnum.NATIVE_ARITHMETIC);
    public static Operator SUBTRACT = new Operator("-", "减去", OperatorTypeEnum.NATIVE_ARITHMETIC);
    public static Operator MULTIPLY = new Operator("*", "乘以", OperatorTypeEnum.NATIVE_ARITHMETIC);
    public static Operator DIVIDE = new Operator("/", "除以", OperatorTypeEnum.NATIVE_ARITHMETIC);

    public static Operator GREATER = new Operator(">", "大于", OperatorTypeEnum.NATIVE_RELATIONSHIP);
    public static Operator GREATER_EQUAL = new Operator(">=", "大于等于", OperatorTypeEnum.NATIVE_RELATIONSHIP);
    public static Operator LESS = new Operator("<", "小于", OperatorTypeEnum.NATIVE_RELATIONSHIP);
    public static Operator LESS_EQUAL = new Operator("<=", "小于等于", OperatorTypeEnum.NATIVE_RELATIONSHIP);

    public static Operator ASSIGN = new Operator("Assign", "赋值为", OperatorTypeEnum.CUSTOM);
    public static Operator INCLUDE = new Operator("Include", "包含", OperatorTypeEnum.CUSTOM);
    public static Operator NOT_INCLUDE = new Operator("NotInclude", "不包含", OperatorTypeEnum.CUSTOM);
    public static Operator VARIABLE = new Operator("Variable", "变量{0}的值", OperatorTypeEnum.CUSTOM);
    public static Operator TIME_DIFF = new Operator("TimeDiff", "{0}减去{1}之间{2}级别的时间差", OperatorTypeEnum.CUSTOM);
    public static Operator RANDOM = new Operator("Random", "{0}—{1}之间的随机数", OperatorTypeEnum.CUSTOM);

    private Operator(String code, String name, OperatorTypeEnum type) {
        this.code = code;
        this.name = name;
        this.type = type;
    }
    /**
     * 符号
     */
    private String code;

    /**
     * 名称
     */
    private String name;
    /**
     * 操作符类型
     */
    private OperatorTypeEnum type;

}
  • 表达式因子 ExpresssionFactor
package com.xxx.rules.engine.domain;

import com.xxx.rules.engine.enums.DataTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 表达式因子
 */
@Data
@AllArgsConstructor
public class ExpressionFactor {

    /**
     * 条件编码。全局唯一
     */
    private String code;
    /**
     * 中文名称
     */
    private String name;
    /**
     * 数据类型
     */
    private DataTypeEnum dataType;

}
  • 值对象 ValueObj
package com.xxx.rules.engine.domain;

import com.xxx.rules.engine.enums.DataTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 值对象
 */
@Data
@AllArgsConstructor
public class ValueObj {

    /**
     * 值
     */
    private Object value;

    /**
     * 值的数据类型
     */
    private DataTypeEnum dataType;

}
  • 规则表达式对象定义 Expression
package com.xxx.rules.engine.domain;

import lombok.Data;
import java.util.ArrayList;
import java.util.List;

/**
 * 规则表达式实体定义。
 * 规则表达式至少由三部分组成:表达式因子、操作符、值对象
 */
@Data
public class Expression {

    public Expression() {}

    public Expression(ExpressionFactor expressionFactor, Operator operator, ValueObj... valueObj) {
        this.factor = expressionFactor;
        this.operator = operator;
        this.valueObjs = new ArrayList<>();
        for(ValueObj obj : valueObj) {
            this.valueObjs.add(obj);
        }
    }

    /**
     * 表达式因子
     */
    private ExpressionFactor factor;
    /**
     * 操作运算符
     */
    private Operator operator;
    /**
     * 值对象
     */
    private List<ValueObj> valueObjs;
    /**
     * 连接下一个表达式片段操作符
     */
    private Operator linkOperator;
    /**
     * 嵌套定义下一个表达式片段
     */
    private Expression innerExpression;

}
  • 条件部分的表达式对象定义 ConditionExpression
package com.xxx.rules.engine.domain;

import lombok.Data;
import java.util.List;

/**
 * 条件表达式
 */
@Data
public class ConditionExpression {

    /**
     * 逻辑运算符
     */
    private Operator logicalOperator;

    /**
     * 子表达式
     */
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值