Drools 6.5 -规则引擎入门

1、规则引擎简介

  规则引擎可以将活动规则和代码解耦,不管规则如何变化,执行端不用动。java开源的规则引擎有:Drools、Easy Rules、Mandarax、IBM ILOG。使用最为广泛并且开源的是Drools。


2、Drools规则引擎原理

  Drools 中的 Rete 算法被称为 ReteOO,表示 Drools 为面向对象系统(Object Oriented systems)增强并优化了 Rete 算法。

Rete 算法

  Rete 在拉丁语中译为”net”,即网络。Rete 匹配算法是一种进行大量模式集合和大量对象集合间比较的高效方法,通过网络筛选的方法找出所有匹配各个模式的对象和规则。

其核心思想是将分离的匹配项根据内容动态构造匹配树,以达到显著降低计算量的效果。Rete 算法可以被分为两个部分:规则编译和规则执行。当Rete算法进行事实的断言时,包含三个阶段:匹配、选择和执行,称做 match-select-act cycle。

rate算法的详细内容可以参考这篇文章:开源规则流引擎实践

Drools架构及原理图

  在 Drools 中,规则被存 放在 Production Memory(规则库)中,推理机要匹配的 facts(事实)被存在 Working Memory(工作内存)中。当时事实被插入到工作内存中后,规则引擎会把事实和规则库里的模式进行匹配,对于匹配成功的规则再由 Agenda 负责具体执行推理算法中被激发规则的结论部分,同时 Agenda 通过冲突决策策略管理这些冲突规则的执行顺序,Drools 中规则冲突决策策略有:

  • 优先级策略
  • 复杂度优先策略
  • 广度策略
  • 深度策略
  • 装载序号策略
  • 随机策略
    在这里插入图片描述

3、入门例子

计算年龄小例子

age> 0 少年
age> 12 青年
age> 24 中年
age > 60 && age <80 老年


4、开发流程

maven

IDEA可以直接创建drools类型的项目,但是无法和maven很好的集成,建议直接新建maven项目用来开发,pom文件需要添加以下依赖:

<dependencies>
        <!-- drools -->
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>6.5.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>6.5.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>6.5.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-decisiontables</artifactId>
            <version>6.5.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>6.5.0.Final</version>
        </dependency>
        <!--log4j-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
项目结构规范

drools项目的规则文件和kmodule.xml必须在main->resources文件夹中创建,其中kmodule.xml需要位于main->resources->META-INF目录下
否则运行的时候会出现无法找到资源文件,抛出空指针的异常
resources目录中,规则文件可以按照分类放在不同的目录中,其所在的目录就是kmodule.xml文件中引用的包名,如

main
=resources
==META-INF
===kmodule.xml
==rules1
===rule.drl
==rules2
===rule.drl

pojo

package com.us.person;

/**
 * Created by yangyibo on 16/12/7.
 */
public class Person {
    private String name;
    private int age;
    private String desc;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String toString() {
        return "[name=" + name + ",age=" + age + ",desc=" + desc + "]";
    }
}
rule.drl
package com.us.person;

import com.us.person.Person;


        function void printName(String name,String desc) {
            System.out.println("name:"+name+" desc:"+ desc);
        }


        rule "boy"
            salience 1
            when
                $p : Person(age > 0);
            then
                $p.setDesc("少年");
                retract($p);
                printName($p.getName(),$p.getDesc());
        end

        rule "youth"
            salience 2
            when
                $p : Person(age > 12);
            then
                $p.setDesc("青年");
                retract($p);
                printName($p.getName(),$p.getDesc());
        end

        rule "midlife"
            salience 3
            when
                $p : Person(age > 24);
            then
                $p.setDesc("中年");
                retract($p);
                printName($p.getName(),$p.getDesc());
        end

        rule "old"
        lock-on-active true

          salience 5
            when
                $p : Person(age > 60 && age <80)

            then
                $p.setDesc("老年");
                update($p);
                printName($p.getName(),$p.getDesc());
        end
kmodule.xml

如果没有 kmodule.xml 文件,在META-INF 文件夹下新建kmodule.xml 文件填写如下内容。

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
	<kbase name="SimpleRuleKBase" packages="com.us.person">
        <ksession name="simpleRuleKSession"/>
	</kbase>
</kmodule>

Test

package com.us.person;

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

/**
 * Created by yangyibo on 16/12/7.
 */
public  class PersonTest {
    static KieSession getSession() {
    
        KieServices ks = KieServices.Factory.get();
        KieContainer kc = ks.getKieClasspathContainer();

        return kc.newKieSession("simpleRuleKSession");
    }

    public static void run() {
            KieSession ks = getSession();

            Person p1 = new Person("白展堂", 68);
            Person p2 = new Person("李大嘴", 32);
            Person p3 = new Person("佟湘玉", 18);
            Person p4 = new Person("郭芙蓉", 8);
            Person p5 = new Person("祝无双", 66);

            System.out.println("before p1 : " + p1);
            System.out.println("before p2 : " + p2);
            System.out.println("before p3 : " + p3);
            System.out.println("before p4 : " + p4);
            ks.insert(p1);
            ks.insert(p2);
            ks.insert(p3);
            ks.insert(p4);
            ks.insert(p5);

            int count = ks.fireAllRules();

            System.out.println("总执行了" + count + "条规则------------------------------");
            System.out.println("after p1 : " + p1);
            System.out.println("after p2 : " + p2);
            System.out.println("after p3 : " + p3);
            System.out.println("after p4 : " + p4);
            System.out.println("after p4 : " + p5);
            ks.dispose();

    }

    public static void main(String[] args) {
        run();
    }
}

输出

before p1 : [name=白展堂,age=68,desc=null]
before p2 : [name=李大嘴,age=32,desc=null]
before p3 : [name=佟湘玉,age=18,desc=null]
before p4 : [name=郭芙蓉,age=8,desc=null]
name:祝无双 desc:老年
name:白展堂 desc:老年
name:祝无双 desc:中年
name:李大嘴 desc:中年
name:白展堂 desc:中年
name:佟湘玉 desc:青年
name:郭芙蓉 desc:少年
总执行了7条规则——————————
after p1 : [name=白展堂,age=68,desc=中年]
after p2 : [name=李大嘴,age=32,desc=中年]
after p3 : [name=佟湘玉,age=18,desc=青年]
after p4 : [name=郭芙蓉,age=8,desc=少年]
after p4 : [name=祝无双,age=66,desc=中年]

参考:drools 6.5 -规则引擎入门

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值