首页 > 其他分享 >droools学习入门

droools学习入门

时间:2022-12-19 22:37:25浏览次数:43  
标签:drools 入门 droools void private 学习 规则 import public


整个目录如下所示:




 

CalculateMiles.java


package com.lin.drools.demo;

/**
* 计算顺序(计算优先级 4选1):
* a:根据 油耗与百公里油耗算总里程
* b:根据速度与时间算总里程
* c:直接指定总里程
* d:无法计算(默认为0)
*
* @author linfenliang
*
*/
public class CalculateMiles {
private int t;// s
private double v;// m/s
private double fuel; // l
private double mileFuel;// mile/l
private double miles;
private double totalMiles;

public int getT() {
return t;
}

public void setT(int t) {
this.t = t;
}

public double getV() {
return v;
}

public void setV(double v) {
this.v = v;
}

public double getFuel() {
return fuel;
}

public void setFuel(double fuel) {
this.fuel = fuel;
}

public double getMileFuel() {
return mileFuel;
}

public void setMileFuel(double mileFuel) {
this.mileFuel = mileFuel;
}

public double getMiles() {
return miles;
}

public void setMiles(double miles) {
this.miles = miles;
}

public double getTotalMiles() {
return totalMiles;
}

public void setTotalMiles(double totalMiles) {
this.totalMiles = totalMiles;
}
}




DroolsConst.java


package com.lin.drools.demo;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public final class DroolsConst {
private static final Logger logger = Logger.getLogger(DroolsConst.class);
private static final DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
private static KnowledgeBuilder builder;
private static KnowledgeBase base;
static {
init();
}

/**
* 初始化builder
*
* @author linfenliang
* @date 2013-3-27
* @version V1.0.0 void
*/
private static void initRuleBuilder() {
List<File> drlList = new ArrayList<File>();
File drlFolder = new File("." + File.separator + "conf");
if (drlFolder.isDirectory()) {
File[] fileArray = drlFolder.listFiles();
for (File file : fileArray) {
if (file.getName().endsWith(".drl")) {
drlList.add(file);
}
}
}
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
for (File file : drlList) {
builder.add(
// ResourceFactory.newClassPathResource(entry.getKey(),
// entry.getValue()),
// ResourceFactory.newUrlResource(path),
ResourceFactory.newFileResource(file), ResourceType.DRL);
}
if (builder.hasErrors()) {
System.err.println("定义的规则有误!");
Iterator<KnowledgeBuilderError> it = builder.getErrors().iterator();
while (it.hasNext()) {
System.err.println(it.next());
}
}
}

/**
* 初始化base
*
* @author linfenliang
* @date 2013-3-27
* @version V1.0.0 void
*/
private static void initRuleBase() {
base = KnowledgeBaseFactory.newKnowledgeBase();
base.addKnowledgePackages(DroolsConst.builder.getKnowledgePackages());
}

/**
* 实例化一个session
*
* @author linfenliang
* @date 2013-3-27
* @version V1.0.0 void
*/
protected static StatefulKnowledgeSession getRuleSession() {
return base.newStatefulKnowledgeSession();
}

private static final void init() {
logger.info("算法规则加载开始." + dformat.format(new Date()));
initRuleBuilder();
initRuleBase();
logger.info("算法规则加载完成." + dformat.format(new Date()));

}
}


NumberPlus.java



package com.lin.drools.demo;

public final class NumberPlus {
private int a;
private int b;
private int result;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
}


RoolsHandler.java


package com.lin.drools.demo;

import org.drools.runtime.StatefulKnowledgeSession;
/**
* <pre>
* <strong>规则引擎</strong>
* 规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中
* 分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据规则做出业务决策。
* <strong>业务规则</strong>
* 一个业务规则包含一组条件和在此条件下执行的操作.它们表示业务规则应用程序的一段业务逻辑。
* 业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技术
* 人员使用面向对象的技术语言或脚本来定制。 
* 业务规则的理论基础是:设置一个或多个条件,当满足这些条件时会触发一个或多个操作。
* <strong>使用场景</strong>
* 复杂企业级项目的开发以及其中随外部条件不断变化的业务规则(business logic),迫切需要
* 分离商业决策者的商业决策逻辑和应用开发者的技术决策,并把这些商业决策放在中心数据库
* 或其他统一的地方,让它们能在运行时(即商务时间)可以动态地管理和修改从而提供软件系统的
* 柔性和适应性。规则引擎正是应用于上述动态环境中的一种解决方法。
* 例:信用卡自动审批流程时:用来判断申请人信息是否合法,并根据申请人的条件(如申请人年龄、年收入、
* 家庭情况、信贷情况、学历等)自动判断申请人的等级,从而实现为申请人提供合适的信用卡额度。
*
* </pre>
* @author linfenliang
*
*/
public final class RoolsHandler {
public static Object getResult(Object obj) {

StatefulKnowledgeSession session = DroolsConst.getRuleSession();
session.insert(obj);
session.fireAllRules();
session.dispose();
return obj;
}

public static void main(String[] args) {
CalculateMiles cal = new CalculateMiles();
cal.setT(300);
cal.setV(40.3);
cal = (CalculateMiles) getResult(cal);
System.out.println(cal.getTotalMiles());

NumberPlus num = new NumberPlus();
// num.setA(123);
// num.setB(456);
num = (NumberPlus) getResult(num);
System.out.println(num.getResult());
}
}



CalcuteMiles.drl


package com.lin.drools.test
#对一个规则文件而言,package是必须定义的,必须放在规则文件第一行。特别的是,package的名字是随意的,不必必须对应物理路径,
#跟java的package的概念不同,这里只是逻辑上的一种区分。同样的package下定义的function和query等可以直接使用。
import com.lin.drools.demo.CalculateMiles;
#导入规则文件需要使用到的外部变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法。
rule "fuelAndMileFuel"
/*
定义一个规则。rule "ruleName"。一个规则可以包含三个部分:
属性部分:定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。
条件部分,即LHS,定义当前规则的条件,如 when Message(); 判断当前workingMemory中是否存在Message对象。
结果部分,即RHS,这里可以写普通java代码,即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。
规则必须有一个名称,并且在一个包中是唯一的。如果你在同一个DRL中定义同名规则两次,在装载时将产生一个错误。
如果你新增的DRL包含一个存在于Packaage中的规则,那新的规则将替换旧规则。如果规则名称中有空格,
需要使用双引号包含(好习惯是定义名称时都使用双引号)

注释的写法:参见本文的注释
*/

salience 4
//salience:设置优先级,按数字大小顺序
lock-on-active true
//
activation-group "calculateMiles"
//
when
#规则指定“when”作为一系列条件的集合(称为LHS),然后在“then”中指定一系列操作(称为RHS)。一个用户经常问的问题是“为什么使用when代替if”。
#“when”之所以取代“if”是因为“if”通常是程序执行过程中的一部分,在某一个特定的时间点它对条件进行检查。而“when”代表着它不约束在特定的评估顺序或时间点,在引擎生命周期的任何时候“when”都可以执行。
$c:CalculateMiles(fuel>0 && mileFuel>0 );
then
#规则的LHS部分跟随when关键字(when最好在单独的一行上),RHS部分跟随then关键字(最好也单独一行)。规则使用end关键字结尾。规则不能进行嵌套。
System.out.println("第一优先级根据油耗计算里程:行程油耗:"+$c.getFuel()+",单位油耗:"+$c.getMileFuel());
$c.setTotalMiles($c.getFuel()*$c.getMileFuel());
System.err.println("计算得到的总里程数为:"+$c.getTotalMiles());
update($c);
end

rule "timeAndSpeed"

salience 3
lock-on-active true
activation-group "calculateMiles"
date-effective "2013-03-25 23:59:59" //起始有效期
date-expires "2015-12-31 23:59:59" //结束有效期
when
$c:CalculateMiles(t>0 && v>0 );
#此处 && 可换成 ,
#or 可用$c:(CalculateMiles(v>0 ) or CalculateMiles(t>0));表示,||不推荐使用
then
System.out.println("第二优先级根据时间和平均速度计算里程:总时间:"+$c.getT()+",平均速度:"+$c.getV());
$c.setTotalMiles($c.getT()*$c.getV());
System.err.println("计算得到的总里程数为:"+$c.getTotalMiles());
update($c);
end

rule "directSet"

salience 2
lock-on-active true
activation-group "calculateMiles"
when
$c:CalculateMiles(miles>0 );
then
$c.setTotalMiles($c.getMiles());
System.err.println("第三优先级直接指定总里程:"+$c.getTotalMiles());
update($c);
end

rule "defaultMiles"

salience 1
lock-on-active true
activation-group "calculateMiles"
when
$c:CalculateMiles(miles<=0 );
then
System.out.println("缺少必要的数据,总里程无法计算!");
end

/*
no-loop:[boolean型,默认false]当规则在推论中对fact进行修改后,可能会导致该规则的重新激活,引起递归。设置no-loop为true可以阻止该规则被再次激活。

salience:[integer型,默认0]每一个规则有一个整数类型的优先级属性,默认为0,这个整数可以使正负数。优先级数字高的规则会比优先级低的规则先执行。

agenda-group:[String型,默认MAIN]Agenda group允许用户对分隔Agenda执行区提供更多的控制。只有在具有焦点的agenda group中的规则才能够激发。

auto-focus:[boolean型,默认false]当规则的auto-focus属性为true时,如果该规则符合激活条件,则该规则所在agenda-group自动获得焦点,允许规则激发。 

activation-group[String型,默认N/A]在同名activation-group中的规则将以互斥的方式激发。这个意思时在这个组中第一条被激发的规则将取消其它规则的激发,即使它们已经在激发队列中。Activation-group属性可以是任何字符,只要所有你需要放在同一个组中的规则中的activation-group属性是相同的即可。

dialect:[String型,默认由Package指定,可能值: "java" or "mvel"]Dialect指定在LHS代码表达式或RHS代码块中使用的语言。当前两种语言有效,Java和MVEL。Dialect可以在Package级别统一指定,而Rule属性中指定的dialect将局部覆盖掉Package中的定义。

date-effective:[包含日期/时间定义的String型,默认N/A]规则只能在date-effective指定的日期和时间之后激活。

date-exptires:[包含日期/时间定义的String型,默认N/A]如果当前时间在date-expires指定的时间之后,规则不能激活。

duration:[long型,默认N/A]Duration指出规则将在指定的一段时间后激发,如果那个时候规则的激活条件还是处于true的情况下。

*/


#详细用法参考:http://wenku.baidu.com/view/98c0e85d312b3169a451a41c.html

NumberPlus.drl


package com.lin.drools.test

import com.lin.drools.demo.NumberPlus;

rule "求和"
salience 8
lock-on-active true
when
$n:NumberPlus();
then
System.out.println("数据符合要求,开始计算");
$n.setResult($n.getA()+ $n.getB());
System.out.println("A="+$n.getA()+",B="+ $n.getB()+",SUM="+$n.getResult());
update($n);
end

rule "设置值"
salience 9
lock-on-active false
when
$n:NumberPlus(a <= 100 );
then

System.out.println("A="+$n.getA()+",B="+$n.getB()+",数据不达标,对数据规范化设置");
$n.setA($n.getA()*2+1);
System.out.println("A="+$n.getA()+",B="+$n.getB());
$n.setB(456);
update($n);
end

执行结果:



log4j:WARN No appenders could be found for logger (com.lin.drools.demo.DroolsConst).
log4j:WARN Please initialize the log4j system properly.
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.
计算得到的总里程数为:12090.0
第二优先级根据时间和平均速度计算里程:总时间:300,平均速度:40.3
12090.0
A=0,B=0,数据不达标,对数据规范化设置
A=1,B=0
A=1,B=456,数据不达标,对数据规范化设置
A=3,B=456
A=3,B=456,数据不达标,对数据规范化设置
A=7,B=456
A=7,B=456,数据不达标,对数据规范化设置
A=15,B=456
A=15,B=456,数据不达标,对数据规范化设置
A=31,B=456
A=31,B=456,数据不达标,对数据规范化设置
A=63,B=456
A=63,B=456,数据不达标,对数据规范化设置
A=127,B=456
数据符合要求,开始计算
A=127,B=456,SUM=583
583


标签:drools,入门,droools,void,private,学习,规则,import,public
From: https://blog.51cto.com/u_5488952/5953904

相关文章

  • Gradle 教程说明 用户指南 第7章 构建Java工程----快速入门
    官网地址:http://www.gradle.org/docs/2.1/userguide/tutorial_java_projects.htmlAbasicJavaproject 一个基础的java工程使用java插件在build.gradle:applyplugin:'......
  • 后网课时代的学习思考
    后网课时代的学习思考时代的洪流奔涌不息,携眷着渺小如尘埃的你我一路走来历经风雨。同样的冬季,寒风凛冽过的12月却迎来一如3年前的点滴悲伤。行走在清零与共存的划事件时......
  • [深度学习] ubuntu18.04配置深度学习环境笔记
    最近装过很多ubuntu18.04系统的nvidia驱动,cuda10.2,cudnn7.6.5,发现每次都会出现一些小问题。总结了具体步骤,做个记录。主要分为三个步骤:驱动安装,cuda安装,cudnn安装。本文主......
  • [深度学习] 深度学习中卷积操作和数学中卷积操作的异同
    date:2017-11-2521:51:08+0800tags:-深度学习在深度学习(机器学习)中,卷积实际上是信号处理中的自相关操作(cross-correlation),而不是数学上的卷......
  • [机器学习] sklearn决策树、随机森林、隐马尔可夫模型
    date:2018-04-1923:36:16+0800tags:-机器学习-Python决策树决策树(DecisionTree)是一种用于处理分类和回归问题的无监督学习算法。如......
  • [编程基础] C++多线程入门8-从线程返回值
    date:2020-05-2917:09:34+0800tags:-编程基础原始C++标准仅支持单线程编程。新的C++标准(称为C++11或C++0x)于2011年发布。在C++11中,引入了新的线程库。因此运行......
  • Docker入门介绍
    1docker组件介绍#Docker:容器技术,资源隔离dotCloudgo写的软件Docker的基础是Linux容器(LXC)等技术LXC的基础上Docker进行了进一步的封装,让用户不......
  • 在前端学习中我遇到的问题以及解决方法总结之一
    练习:首先在页面中写四个button,点击其中一个按钮在控制台打印点击了那个按钮的值首次思考后实现的代码遇到的问题:采用for循环监听事件绑定函数的过程中没有考虑函数作用......
  • 入门练习4-17
    太简单,不知道出题者的目的是什么#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>intmain(){inta,i;printf("n的值:");scanf("%d",&a);for(i=1;i<=a;......
  • PaddleOCR学习笔记 00-PaddleOCR简介
    PaddleOCR学习笔记00-PaddleOCR简介图片可能不全,大家可以观看b站的视频。视频链接:https://www.bilibili.com/video/BV1nf4y1U7RX?p=4官网地址:https://github.com/PaddlePad......