跳至主要內容

规则引擎 Drools

大约 2 分钟

规则引擎 Drools

DROOLS(JBOSS RULES)具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。

开发步骤

  1. 获取 KieServices
  2. 获取 KieContainer
  3. KieSession
  4. insert.fact
  5. 触发规则;
  6. 关闭 KieSession

pom.xml

<!-- https://mvnrepository.com/artifact/org.drools/drools-compiler -->
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.73.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-mvel</artifactId>
    <version>7.73.0.Final</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.1</version>
    <scope>test</scope>
</dependency>

src/main/resources/META-INF/kmodule.xml

<?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="myKbase1" packages="rules" default="true">
        <ksession name="ksession-rule" default="true"/>
    </kbase>
</kmodule>

src/main/java/org/example/entity/Order.java

package org.example.entity;

public class Order {
    private int amount;
    private int score;

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

src/main/resources/rules/score-rules.drl

package rules;

import org.example.entity.Order;

rule "score_1"
when
    $order:Order(amount <= 100)
then
    $order.setScore(0);
    System.out.println("触发了规则:100元以下,不加分");
end

rule "score_2"
when
    $order:Order(100 < amount && amount <= 500)
then
    $order.setScore(100);
    System.out.println("触发了规则:100-500元,加100分");
end

rule "score_3"
when
    $order:Order(500 < amount)
then
    $order.setScore(500);
    System.out.println("触发了规则:500元以上,加500分");
end

src/test/java/org/example/DroolsTests.java

KieKnowledge Is Everything 的缩写。

package org.example;

import org.example.entity.Order;

import org.junit.jupiter.api.Test;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class DroolsTests {
    @Test
    public void test1() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();

        Order order = new Order();
        order.setAmount(100);

        kieSession.insert(order);
        kieSession.fireAllRules();
        kieSession.dispose();
    }
}

output

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
触发了规则:100元以下,不加分

Process finished with exit code 0

业界实践

在实践中,我们发现 Drools 方案有以下几个优缺点:

优点

  • 策略规则和执行逻辑解耦方便维护。

缺点

  • 业务分析师无法独立完成规则配置:由于规则主体 DSL 是编程语言(支持 Java, Groovy, Python),因此仍然需要开发工程师维护。
  • 规则规模变大以后也会变得不好维护,相对硬编码的优势便不复存在。
  • 规则的语法仅适合扁平的规则,对于嵌套条件语义(then 里嵌套 when…then 子句)的规则只能将条件进行笛卡尔积组合以后进行配置,不利于维护。

参考链接

(全文完)