规则引擎-Easy rule

规则引擎-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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu20.04中设置包含ros节点的文件自启动

若文件里包含了ros话题的发布和接收&#xff0c;那么设置自启动时&#xff0c;应该首先将roscore设置为自启动。 首先确保roscore有一个systemd服务文件。如果还没有&#xff0c;需要在/etc/systemd/system/下创建一个。例如&#xff0c;一个基本的roscore.service文件可能如下…

IO进程线程(六)进程

文章目录 一、进程状态&#xff08;二&#xff09;进程状态切换实例1. 实例1 二、进程的创建&#xff08;一&#xff09;原理&#xff08;二&#xff09;fork函数--创建进程1. 定义2. 不关注返回值3. 关注返回值 &#xff08;三&#xff09; 父子进程的执行顺序&#xff08;四&…

OCP 备份 OceanBase集群

注:OCP版本为4.2.1,OceanBase版本为 社区版4.2.1.0 手动备份 进行合并 在手动进行备份数据之前&#xff0c;建议进行一次OB集群合并(不影响业务的前提下)&#xff0c;关于合并的概念请参考OB官网。 点击进入要备份的OB集群 点击左侧工具栏中的 合并管理&#xff0c;在 基本信息…

【前端基础】CSS介绍|CSS选择器|常用CSS

目录 一、CSS介绍 1.1 什么是CSS 1.2 基本语法规范 1.3 引⼊⽅式 1.4 规范 &#x1f4a1;二、CSS选择器 1. 标签选择器 2. class选择器 3. id选择器 4. 复合选择器 5. 通配符选择器 三、常用CSS 3.1 color 3.2 font-size 3.3 border 3.4 width/height 3.5 padd…

安全生产新篇章:可燃气体报警器检验周期的国家标准解读

随着工业化进程的加快&#xff0c;安全生产成为了重中之重。 可燃气体报警器作为预防火灾和爆炸事故的重要设备&#xff0c;其准确性和可靠性直接关系到企业的生产安全和员工的生命财产安全。 因此&#xff0c;国家对可燃气体报警器的检验周期有着明确的规定&#xff0c;以确…

密塔AI:联网搜索工具,可以搜索科研文献

文章目录 简介功能探究 简介 作为联网搜索AI&#xff0c;肯定得有能力做个自我介绍&#xff0c;在搜索框中输入“密塔AI简介”&#xff0c;其处理过程如下&#xff0c;看来主打一个没有广告&#xff0c;直达结果。 回复如下 秘塔AI搜索(metaso.cn)于2024年初上线&#xff0c;它…

若依 ruoyi-vue element-ui el-cascader 级联选择器 选择任意一级选项,去掉单选按钮,选中点击后隐藏

Cascader 级联选择器 选择任意一级选项&#xff0c;去掉单选按钮。 这兄弟文章写的可以&#xff0c;查了一堆文章&#xff0c;基本搞完才发现。 官方的例子不支持选中后自动关闭&#xff0c;要点击旁边空白&#xff0c;并且单选框太小了。 <el-form-item label"所属地…

CSS双飞翼布局

双飞翼布局是一种经典的CSS布局模式&#xff0c;主要用于实现左右两列固定宽度&#xff0c;中间列自适应的布局。 比如&#xff1a;写一个左中右布局占满全屏&#xff0c;其中左、右两块固定宽 200px&#xff0c;中间自适应&#xff0c;要求先加载中间块。 <!DOCTYPE html…

一文看懂llama2(原理模型训练)

自从Transformer架构问世以来&#xff0c;大型语言模型&#xff08;Large Language Models, LLMs&#xff09;以及AIGC技术的发展速度惊人&#xff0c;它们不仅在技术层面取得了重大突破&#xff0c;还在商业应用、社会影响等多个层面展现出巨大潜力。随着ChatGPT的推出&#x…

Nginx02-Nginx虚拟主机介绍、日志介绍、Location规则介绍

目录 写在前面NginxNginx处理用户请求流程虚拟主机虚拟主机的分类基于域名的虚拟主机基于端口的虚拟主机基于IP的虚拟主机 Nginx日志错误日志案例 访问日志访问格式变量案例 Location规则案例1案例2Location规则小结 写在前面 这是Nginx第二篇&#xff0c;内容为Nginx处理用户请…

【WEB系列】过滤器Filter

Filter&#xff0c;过滤器&#xff0c;属于Servlet规范&#xff0c;并不是Spring独有的。其作用从命名上也可以看出一二&#xff0c;拦截一个请求&#xff0c;做一些业务逻辑操作&#xff0c;然后可以决定请求是否可以继续往下分发&#xff0c;落到其他的Filter或者对应的Servl…

mysql中optimizer trace的作用

大家好。对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;我们只能通过EXPLAIN语句查看到最后 优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。于是在MySQL5.6以及之后的版本中&#xff0c;MySQL新增了一个optimi…

量化投资分析平台 迅投 QMT(三)字典数据下载后读取成Dataframe形式

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用如何读取下载好的数据出来上代码历史帖子 迅投 QMT 我目前在使用 两个月前&#xff08;2024年4月&#xff09;迅投和CQF有一个互动的活动&#xff0c;进行了平台的一个网上路演&…

初始C++(类与对象)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 文章目录 前言一.引用二.内联函数三.类和对象总结 前言 之前讲c的命令空间和第一个程序的运行&#xff0c;继…

adb shell service命令与SurfaceFlinger调试

“ 在Android上有丰富的shell命令便于开发者用来调试程序&#xff0c;非常方便&#xff0c;本文简单说明下service命令的用法。” 01 基本用法 首先看一下使用说明&#xff0c;带上参数-h 或 -&#xff1f; $ adb shell service -h Usage: service [-h|-?]service listservi…

STM32 MDK Keil5软件调试功能使用(无需连接硬件)

MDK Keil5 在线仿真STM32&#xff08;无需连接硬件&#xff09; 首先点击工具栏的魔术棒配置一下&#xff1a;&#xff08;记得选择自己的STM32芯片类型&#xff09; 开启调试 使用逻辑分析仪查看IO输出 会打开这个界面&#xff0c;点击左边的setup按钮 会打开这个窗口&am…

交易量突破 3000 亿美元,去中心化衍生品协议 APX Finance 成最大的黑马?

“APX Finance 总交易量现已突破 3000 亿美元&#xff0c;已然成为链上衍生品赛道的主力军” 自 2021 年链上衍生品市场进入萌芽期以来&#xff0c;该板块始终保持着较高的市场增速&#xff0c;即便如此该领域仍旧存在极大的发展空间。一方面&#xff0c;衍生品板块交易量目前占…

【Kubernetes】k8s集群的污点、容忍、驱逐 以及排障思路

污点和容忍以及驱逐 一、污点&#xff08;Taint&#xff09; 污点介绍 节点亲和性&#xff0c;是Pod的一种属性&#xff08;偏好或硬性要求&#xff09;&#xff0c;它使Pod被吸引到一类特定的节点。Taint 则相反&#xff0c;它使节点能够排斥一类特定的 Pod。 Taint 和 Tol…

Docker 常用命令以及镜像选择

前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&#xff0c;我们往往容易陷入工作的漩涡&#xff0c;忘记了停下脚步&#xff0c;感受周围的世界。让我们一起提醒自己&#xff0c;要适时放慢脚步…

PS系统教程12

画笔模式-绘画模式 相反组&#xff1a;理解一组即可 叠加、柔光重点理解&#xff0c;后面只是细微的差别差值-排除相当于胶卷留下的底片那样的效果。 正常和溶解的对比 正常-背后 效果&#xff1a;重叠的部分在就图层后面。 清楚与橡皮擦一样。 变暗 原理&#xff1a;比这个…