规则引擎-Easy rule

news2025/1/22 9:03:21

规则引擎-Easy rule

最近有几个项目中都出现了根据XX条件执行XX方法的业务,在动手之前脑中总会下意识的发现如果按照常规的去写代码,无论使用何种设计模式,都会出现不同程度上的代码冗余或大量if-else判断。

甚至说判断XX条件的代码和执行XX方法的代码,非常容易出现上下级调用的关系;

在多的这些功能熟练之后,规则引擎可以完美的适配这种 根据XX条件执行XX方法 的业务;

什么是规则引擎

如其名,定义规则的执行引擎,是一套解决业务代码与执行其业务规则分离的解决方案或组件;

举个例子:有一个功能为,当用户输入A时,将用户的信息更新为B

如果按照常规代码来说,伪代码为:

public void update(String mess) {
    if(mess.equlas("A")){
    	//更新
	}
}

如果使用规则引擎则变成:

public void rule(String mess){
        Rules rules = new Rules();
        rules.register(new RuleBuilder()
                .when((facts -> facts.get("mess").equals("A")))
                .then(facts -> {
                    System.out.println("更新B");
                })
                .build());
        RulesEngine rulesEngine = new DefaultRulesEngine();
        Facts facts = new Facts();
        facts.put("mess","A");
        rulesEngine.fire(rules,facts);
}

可以直观的感受到,怎么使用了规则引擎之后代码变多了而且变复杂了?

且慢,让我们认真缕一缕;

现在我们需要添加一个新逻辑,当用户输入B时,将信息更新为C;

在常规中,有两种选择:

  1. 继续往后叠If-else或者使用switch
  2. 使用策略模式,将输入的内容作为策略key;

在规则引擎中,有两种选择:

  1. 继续在.when()和.then()中堆叠
  2. 将.when()和.then()的实际动作抽离成策略方法,各做各的事。

或许还不够直观看出改变,那么我再添加一个前提,如果是 当用户输入???,其中n个条件,只需要满足其中之一,那么就执行更新动作;

在常规中,是不是只有两种办法:

  1. 数据库配置
  2. 写死一个map,进行判断

再规则引擎中,我只需要将从.when()中抽离出来的校验解析式进行通过配置即可,比方说使用Sql语句作为.when()方法中的结果;

规则为:SELECT * FROM xxx WHERE mess IN ('A','B','C','D','E')

构建的facts.put("mess",mess); 就可以在不动任何代码的前提下仅通过已经抽离的.when()中的表达式 规则 完成新规则-执行逻辑的拓展;

其结构组成为:

Easy-rule

在JAVA几大主流的规则引擎:

规则引擎优势缺点
DroolsDrools 支持复杂的规则和事件处理,具有强大的表达能力。
它提供了一个易于使用的 DSL (领域特定语言) 来表示规则,使得非技术人员也能够理解和维护规则。
学习曲线较陡,对于新手来说可能需要一定的时间来学习和掌握。
在处理大规模数据时性能可能不如其他规则引擎。
JBossRulesJBoss Rules 是 Drools 的早期版本,提供了类似的规则引擎功能。由于是 Drools 的早期版本,可能缺少一些新功能和改进。
Easy RulesEasy Rules 是一个轻量级的 Java 规则引擎,适用于简单的规则场景。
易于学习和使用,适合快速集成到项目中。
不适用于复杂规则场景,功能相对有限。
Camel KCamel K 是 Apache Camel 的 Kubernetes 版本,可以与 Kubernetes 环境集成。
具有强大的路由和转换功能,适用于复杂的集成场景。
相对于专门的规则引擎,可能在规则管理和表达能力上略显不足。

EasyRule适用于目前遇到的绝大多数的项目,且即使需要复杂的规则场景,也可以通过其余的表达式组件去构建自定义的规则表达式,比如前文案例中提到的Sql表达式;

简单的概括一下适用教程:

引入

<dependency>
    <groupId>org.jeasy</groupId>
    <artifactId>easy-rules-core</artifactId>
    <version>4.1.0</version>
</dependency>

使用

https://github.com/j-easy/easy-rules

这里不介绍使用注释的方式,推荐链式编程,代码更加直观清晰:

public void runle(){
Rules rules = new Rules();
rules.register(new RuleBuilder()
        .when((facts -> return true;)
        .then(facts -> {
            System.out.println("hellow");
        })
        .build());
RulesEngine rulesEngine = new DefaultRulesEngine();
Facts facts = new Facts();
rulesEngine.fire(rules,facts);
}

也可以使用文件的方式定义规则

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
  - "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

Facts 中则是放入在.when()判断时需要用到的需要,通过put,get方法key-value的形式存储;

增强

对于简单的规则业务来说,往往都是 X=X,则执行?的判断;因此简单的可以直接通过yaml文件配置死;

但是在需要稍微复杂判断的业务中,则需要开发者自行增强;

比方说我现在有多个规则,有两种情况一是需要当这些规则都成立的时候才执行更新,二是只要其中一个规则成立就执行:

我们可以自定义一个规则执行类:

public class AllEstablishRule {

    private List<Rule> rules;

    private Runnable runnable;

    public AllEstablishRule(List<Rule> rules, Runnable runnable) {
        this.rules = rules;
        this.runnable = runnable;
    }

    public boolean evaluate(Facts facts) {
        boolean ok = false;
        for (Rule rule : rules) {
            ok = rule.evaluate(facts);
            if (!ok) break;
        }
        return ok;
    }

    public void execute(Facts facts) {
        if (evaluate(facts)) {
            runnable.run();
        }
    }
}

使用为:


        AllEstablishRule allEstablishRule = new AllEstablishRule(CollectionUtil.newArrayList(new RuleBuilder()
                .when((facts -> facts.get("mess").equals("A")))
                .build(),new RuleBuilder()
                .when((facts -> facts.get("mess").equals("B")))
                .build()),()->{
            System.out.println("更新");
        });
        Facts facts = new Facts();
        facts.put("mess","A");
        allEstablishRule.execute(facts);

再比如,当需要复杂判断时,我们可以对.when()的判断动作作手脚;

比方说上述提到的SQL表达式,就可以通过使用 com.alibaba.druid.sql 包下的类解析SQL,使一个查询语句中的条件

where name = '小红' AND age = 14 OR sex = '男'

这些拼接成一个代码逻辑中的 &|判断以及 = ,in 的判断。

总结

因为在使用Easy-rule的体验中还没遇到解决不了的问题,所以还没涉及过其余的规则引擎,相信未来终有机会接触到他们;

Easy-rule再git社区上的活跃为3年前,并且其余的规则引擎的社区活跃度也远没有我们常用的框架、工具的多,可以看出规则引擎在设计中以及是一种非常成熟的解决方案了。

版权声明:本站原创文章,于2024-04-08,乐云一发表
转载请注明:https://leyunone.com/java/easy-rule.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1789733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

26、matlab多项式曲线拟合:polyfit ()函数

1、polyfit 多项式曲线拟合 语法 语法&#xff1a;p polyfit(x,y,n) 返回次数为 n 的多项式 p(x) 的系数&#xff0c;该阶数是 y 中数据的最佳拟合&#xff08;基于最小二乘指标&#xff09;。 语法&#xff1a;[p,S] polyfit(x,y,n) 还返回一个结构体 S 语法&#xff1a;[…

学会这14大招,30天涨粉两三千没问题!沈阳新媒体运营培训

很多小白在刚转入公司做新媒体时&#xff0c;基本都是从帮助公司运营账号开始的。但不同于个人号&#xff0c;一个企业本身是没有ip属性的&#xff0c;它的风格、调性等&#xff0c;都需要通过你的运营&#xff0c;让它变成一个活灵活现的、赋予独立个性人设的账号。 目前&…

IC设计企业致力于解决的HPC数据防泄漏,到底该怎么做?

对于半导体IC设计企业来说&#xff0c;芯片设计、验证、仿真使用HPC环境现在已逐渐成为趋势&#xff0c;主要原因在于原来的工作流程存在较多的缺陷&#xff1a; 性能瓶颈&#xff1a;仿真、设计、验证、生产过程中&#xff0c;前端仿真需要小文件高并发低时延的读写和巨量元数…

Ubuntu server 24.04 (Linux) 搭建DNS服务器 通过Nginx实现UDP/TCP负载均衡 轻量级dnsmasq服务器

一 系统运行环境 testtest:~$ cat /etc/os-release PRETTY_NAME"Ubuntu 24.04 LTS" NAME"Ubuntu" VERSION_ID"24.04" VERSION"24.04 LTS (Noble Numbat)" VERSION_CODENAMEnoble IDubuntu ID_LIKEdebian HOME_URL"https://www.…

专业130+总分400+四川大学951信号与系统考研经验川大电子信息与通信工程,真题,大纲,参考书。教材。

今年四川大学951信号与系统专业课130&#xff08;据我所知没有140以上的今年&#xff09;&#xff0c;总分400&#xff0c;顺利上岸川大&#xff0c;回顾一下自己这一年的复习&#xff0c;希望自己的经历可以对大家复习有所借鉴&#xff0c;也是对自己的考研画上句话。专业课&a…

2024-06-05 Android app jni里面c语言函数申请的局部变量数组过大会导致程序崩溃的问题分析

一、下面是一个app jni里面一个函数&#xff0c;函数里面定义一个数组&#xff0c;实际运行的时候发现数组过大的时候会导致app崩溃。 JNIEXPORT jint JNICALL JNI_FUNCTION(native_1getcapture_1data)(JNIEnv *env, jobject obj,jbyteArray des_data,jbyteArray src_data,jin…

【Kubernetes】k8s的调度约束(亲和与反亲和)

一、调度约束 list-watch 组件 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令&#xff0c;在 Node 节点上面建立 Pod 和…

【Qt】Frame和Widget的区别

1. 这两个伙计有啥区别&#xff1f; 2. 区别 2.1 Frame继承自Widget&#xff0c;多了一些专有的功能 Frame Widget 2.2 Frame可以设置边框

Socket编程学习笔记之TCP与UDP

Socket&#xff1a; Socket是什么呢&#xff1f; 是一套用于不同主机间通讯的API&#xff0c;是应用层与TCP/IP协议族通信的中间软件抽象层。 是一组接口。在设计模式中&#xff0c;Socket其实就是一个门面模式&#xff0c;它把复杂的TCP/IP协议族隐藏在Socket接口后面&#…

视频监控汇聚平台LntonCVS国标GB28181协议实现语音对讲功能

在当今这个智能技术飞速发展的时代&#xff0c;人工智能已经成为了电子产品领域的一股不可忽视的热门趋势。随着科技的不断进步&#xff0c;越来越多的电子产品开始融入人工智能技术&#xff0c;从而为其开拓了全新的发展路径。在这个大背景下&#xff0c;安防摄像头无插件直播…

硬件高效的线性注意力机制Gated Linear Attention论文阅读

0x0. 前言 上篇文章 flash-linear-attention中的Chunkwise并行算法的理解 根据GLA Transformer Paper&#xff08;https://arxiv.org/pdf/2312.06635 作者是这位大佬 sonta&#xff09;通过对Linear Attention的完全并行和RNN以及Chunkwise形式的介绍理解了Linear Attention的…

Isaac Lab支持的强化学习框架介绍

在Isaac Lab中使用rl_games强化学习框架进行机械臂训练实验 python source/standalone/workflows/rl_games/train.py --taskIsaac-Franka-Cabinet-Direct-v0 使用 RL 代理进行培训 — Isaac Lab 文档 --- Training with an RL Agent — Isaac Lab documentation (isaac-sim.g…

企业级win10电脑下同时存在Python3.11.7Python3.6.6,其中Python3.6.6是后装的【过程与踩坑复盘】

背景: 需要迁移原始服务器的上的Python3.6.6+Flask项目到一个新服务器上, 新服务器上本身存在一个Python3.11.7, 所以这涉及到了一个电脑需要装多个Python版本的问题 过程: 1-确定新电脑版本【比如是32还是64位】 前面开发人员存留了两个包,是python-3.6.6.exe和pytho…

Java Web学习笔记6——盒子模型

视频标签&#xff1a;<video> src: 规定视频的URL controls&#xff1a;显示播放控件 width&#xff1a;播放器的宽度 height&#xff1a;播放器的高度 音频标签&#xff1a;<audio> src: 规定音频的URL controls: 显示播放控件 段落标签&#xff1a;<p&g…

Kafka之Broker原理

1. 日志数据的存储 1.1 Partition 1. 为了实现横向扩展&#xff0c;把不同的数据存放在不同的 Broker 上&#xff0c;同时降低单台服务器的访问压力&#xff0c;我们把一个Topic 中的数据分隔成多个 Partition 2. 每个 Partition 中的消息是有序的&#xff0c;顺序写入&#x…

GNU Radio创建qt time plot python OOT块

文章目录 前言一、创建自定义的 OOT 块1、安装相应依赖2、创建 OOT 块3、修改相关4、编译及安装 OOT 块 二、测试1、grc 图2、运行结果 三、资源自取 前言 官方提供的绘制时域波形的 block 名字叫做 QT GUI Time Sink&#xff0c;其底层实现是用 C 写的&#xff0c;但是我发现…

webf 开发工具:数据库持久层基础文件生成工具

WZW.SqlMapHelpForJava是运行在.Net Framework4.0上的数据库持久层基础文件生成工具&#xff0c;支持多种关系型数据库的持久层基础文件、Java类的生成以及对配置文件的更新&#xff0c;与webf框架进行紧密配合&#xff0c;减少了数据库持久层基础文件编写工作量&#xff0c;提…

比瓴科技以何魅力吸引安全大牛?

今年4月&#xff0c;专注于软件供应链安全的行业领导厂商比瓴科技宣布&#xff0c;与元豚科技战略合并&#xff0c;元豚科技创始人唐誉聪加入比瓴&#xff0c;担任合伙人及研发副总裁一职。唐誉聪表示&#xff0c;将携手比瓴共同推动持续应用安全平台(ASPM)的发展&#xff0c;将…

电器公司2套PROE如何满足20人使用?

电器公司的日常运营高度依赖于各类软件工具&#xff0c;其中PROE作为广泛应用于产品设计领域的软件&#xff0c;在电器厂公司的生产流程中扮演着举足轻重的角色。如何合理配置和管理PROE软件资源&#xff0c;以满足20人同时使用的需求&#xff0c;是许多电器厂公司面临的实际问…

人工智能--深度神经网络

目录 &#x1f349;引言 &#x1f349;深度神经网络的基本概念 &#x1f348;神经网络的起源 &#x1f34d; 神经网络的基本结构 &#x1f349;深度神经网络的结构 &#x1f348; 卷积神经网络&#xff08;CNN&#xff09; &#x1f348;循环神经网络&#xff08;RNN&…