Java Drools5.1 规则流基础【示例】

一、问题描述



假设雇员Employ有:

学历信息 eduInfo, 简历信息 resume,

考核信息 annualExam 和奖惩信息 awardPunish;

要确定其:

基本工资 basicSalary, 职务工资 dutySalary,

分红金额 bonus 和 总工资 totalSalary.



规则如下:

【1】学历决定基本工资(basicSalary):

====>本科1500研究生2500

【2】简历决定职务工资(dutySalary) :

====>技术2000管理4500

【3】年度考核决定分红(bonus):

====>分红总金额1000

==>考核结果:

==>优秀100%(1000);良好90%(900);

合格60%(600); 不合格0%(0);

【4】奖惩决定计算最终工资与【123】项工资之和的比例:

====>奖励:*110%(+10%)

====>惩罚:*90%(-10%)

====>无:*100%(0%)

【5】计算总工资: (【1】+【2】+【3】)*【4】



二、问题分析



1.基本流程:



P【计算基本工资,计算职务工资,计算分红, 计算奖惩比例】

====>计算总工资(根据奖惩情况)

其中,P[i,...,k]表示任务i,...,k并发执行,====>表示顺序执行。

即有:P[1,2,3, 4] ===> 5



三、概要设计



【1】类Employ的设计:

【2】规则文件的编写和组织:

==>学历规则文件:EduInfoRule.drl

==>简历规则文件:ResumeRule.drl

==>分红规则文件:BonusRule.drl

==>奖惩规则文件:AwardPunish.drl

==>计算总工资规则:TotalRule.drl

【3】规则文件的组合(规则流):



==>EduInfo.drl含规则组basic_salary

==>ResumeRule.drl含规则组duty_salary

==>BonusRule.drl含规则组bonus_salary

==>AwardPunish.drl含规则组award_punish

==>TotalRule.drl含规则组sum_salary



组合方式:

[start]---> P[basic_sal ary , duty_salary, bonus_salary, award_punish]

--->sum_salary ---> [end]




其中:P表示并发,--->表示顺序 【规则流图在后面的实现中给出】



【4】编写测试文件:EmployTest.java


四、详细设计



【1】使用EclipseIDE作为开发环境,drools5.1作为规则引擎

【2】为简单起见,Employ类的属性作了简化处理,

eduInfo, resume , annualExam, awardPunish均为String,

basic{duty,bonus,total}_salary , percent作为double类型。

五、规则文件及规则流



EduInfoRule.drl:

package myrules;
import sample.Employ;

rule"Bachelor"
ruleflow-group"basic_salary"
when
emp:Employ(eduInfo =="bachelor");
then
System.out.println("execrule Bachelor ... ");
emp.setBasicSalary(1500);
end

rule"Master"
ruleflow-group"basic_salary"
when
emp:Employ(eduInfo=="master")
then
System.out.println("execrule Master ... ");
emp.setBasicSalary(2500);
end


Resume.drl

package myrules
import sample.Employ;

rule"Technician"
ruleflow-group"duty_salary"
when
emp:Employ(resume=="tech")
then
System.out.println("execrule Technician ... ");
emp.setDutySalary(2000);
end

rule"Manager"
ruleflow-group"duty_salary"
when
emp:Employ(awardPunish=="manager")
then
System.out.println("execrule manager ... ");
emp.setDutySalary(4500);
end


BonusRule.drl

package myrules
import sample.Employ;

rule"Excellent"
ruleflow-group"bonus_salary"
when
emp: Employ(annualExam=="excellent")
then
System.out.println("execrule Excellent ... ");
emp.setBonus(1000*1.0);
end

rule"Good"
ruleflow-group"bonus_salary"
when
emp: Employ(annualExam=="good")
then
System.out.println("execrule Good ... ");
emp.setBonus(1000*0.9);
end

rule"Common"
ruleflow-group"bonus_salary"
when
emp: Employ(annualExam=="common")
then
System.out.println("execrule Common ... ");
emp.setBonus(1000*0.6);
end

rule"failing"
ruleflow-group"bonus_salary"
when
emp: Employ(annualExam=="failing")
then
System.out.println("execrule failing ... ");
emp.setBonus(1000*0.0);
end


AwardPunish.drl


packagemyrules
importsample.Employ;

rule"Award"
ruleflow-group"award_punish"
when
emp:Employ(awardPunish=="award")
then
System.out.println("execrule Award ... ");
emp.setPercent(1.10);
end

rule"Punishment"
ruleflow-group"award_punish"
when
emp:Employ(awardPunish=="punish")
then
System.out.println("execrule Punishment ... ");
emp.setPercent(0.90);
end

rule"None"
ruleflow-group"award_punish"
when
emp:Employ(awardPunish=="none")
then
System.out.println("execrule None ... ");
emp.setPercent(1.00);
end


TotalRule.drl


package myrules
import sample.Employ;

rule"Total"
ruleflow-group"sum_salary"
when
emp: Employ()
then
System.out.println("execrule Total ... ");
double total =emp.getBasicSalary() + emp.getDutySalary() +
emp.getBonus();
emp.setTotalSalary(total*emp.getPercent());
end



[img]http://dl2.iteye.com/upload/attachment/0094/5153/fcafa4e7-5c2c-347a-bc25-6224d3cd465e.png[/img]


注意:

[1]Split结点类型为OR,约束选择alwaystrue.表示选择其规则组中所有符合事实的规则进行并发执行;

[2] Join结点类型为AND,表示当且进当上述规则组均执行完毕后,才执行后面的规则或进程。

[img]http://dl2.iteye.com/upload/attachment/0094/5155/ce64b3ad-96ce-3ada-a411-e9e1b15f2509.png[/img]


六、测试代码:



Employ:

package sample;

public class Employ {

public static final double BONUS = 1000;

private String eduInfo;
private String resume;
private String annualExam;
private String awardPunish;

private double basicSalary;
private double dutySalary;
private double bonus;
private double percent;

private double totalSalary;

public String getEduInfo() {
return eduInfo;
}
public void setEduInfo(String eduInfo) {
this.eduInfo = eduInfo;
}
public String getResume() {
return resume;
}
public void setResume(String resume) {
this.resume = resume;
}
public String getAnnualExam() {
return annualExam;
}
public void setAnnualExam(String annualExam) {
this.annualExam = annualExam;
}
public String getAwardPunish() {
return awardPunish;
}
public void setAwardPunish(String awardPunish) {
this.awardPunish = awardPunish;
}

public double getBasicSalary() {
return basicSalary;
}
public void setBasicSalary(double basicSalary) {
this.basicSalary = basicSalary;
}

public double getDutySalary() {
return dutySalary;
}
public void setDutySalary(double dutySalary) {
this.dutySalary = dutySalary;
}

public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}

public double getPercent() {
return percent;
}
public void setPercent(double percent) {
this.percent = percent;
}

public double getTotalSalary() {
return totalSalary;
}
public void setTotalSalary(double totalSalary) {
this.totalSalary = totalSalary;
}

public String toString() {
return "[" + eduInfo + " " + resume + " " + annualExam + " " +
awardPunish + " " + basicSalary + " " + dutySalary + " " +
bonus + " " + totalSalary + "]";
}

}


EmployTest:

package sample;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class EmployTest {

public static void main(String[] args) {

try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// go !
Employ emp = new Employ();
emp.setEduInfo("master");
emp.setResume("tech");
emp.setAnnualExam("good");
emp.setAwardPunish("award");
ksession.insert(emp);
ksession.startProcess("myrules.salary");
ksession.fireAllRules();
System.out.println("Basic Salary: " + emp.getBasicSalary());
System.out.println("Duty Salary: " + emp.getDutySalary());
System.out.println("Bonus : " + emp.getBonus());
System.out.println("rate : " + emp.getPercent());
System.out.printf("Total Salary: %.0f" , emp.getTotalSalary());
logger.close();
} catch (Throwable t) {
t.printStackTrace();
}

}

private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("rules/EduInfoRule.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("rules/ResumeRule.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("rules/BonusRule.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("rules/AwardPunish.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("rules/TotalRule.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("rules/salary.rf"), ResourceType.DRF);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}

}


测试结果:

execrule Technician ...

execrule Master ...

execrule Good ...

execrule Award ...

execrule Total ...

BasicSalary: 2500.0

DutySalary: 2000.0

Bonus : 900.0

rate : 1.1

TotalSalary: 5940





七、总结


Javadrools规则流基础:


【1】掌握规则引擎的基本工作原理;

【2】掌握规则文件的编写;

【3】掌握规则流图的绘制及应用程序集成。

【4】掌握规则组合的两种基本方式【并发和顺序】的实现方式。


下一步:


【1】更复杂的规则组合;

【2】规则文件的组织、管理;

【3】规则文件的自动生成;

【4】用户自定义规则;



NOTE: 关于XP下的示例作了一些修改,主要增加了XML格式的规则流文件及一个简单的自动生成顺序规则流的方法。已经上传至CSDN下载,请在下面网址下载:http://download.csdn.net/source/3462802
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值