Drools一个很好的例子

逃离我推掉我的手 2022-07-18 11:58 450阅读 0赞

转自http://www.360doc.com/content/15/0701/15/5054188\_481943680.shtml

一、问题描述

假设雇员 Employ 有:

  1. 学历信息 eduInfo , 简历信息 resume ,
  2. 考核信息 annualExam 和奖惩信息 awardPunish

要确定其:

  1. 基本工资 basicSalary ,职务工资 dutySalary
  2. 分红金额 bonus 总工资 totalSalary .

规则如下:

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

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

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

  1. ====> 技术 2000 管理 4500

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

  1. ====> 分红总金额 1000
  2. ==> 考核结果:
  3. ==> 优秀 100% 1000 );良好 90% 900 );
  4. 合格 60% 600 ); 不合格 0% 0 );

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

  1. ====> 奖励: \* 110% +10%
  2. ====> 惩罚: \* 90% -10%
  3. ====> 无: \* 100% 0%

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

二、问题分析

  1. 基本流程:

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

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

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

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

三、概要设计

【 1 】类 Employ 的设计:

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

  1. ==> 学历规则文件: EduInfoRule.drl
  2. ==> 简历规则文件: ResumeRule.drl
  3. ==> 分红规则文件: BonusRule.drl
  4. ==> 奖惩规则文件: AwardPunish.drl
  5. ==> 计算总工资规则: TotalRule.drl

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

  1. ==> EduInfo.drl 含规则组 basic\_salary
  2. ==> ResumeRule.drl 含规则组 duty\_salary
  3. ==> BonusRule.drl 含规则组 bonus\_salary
  4. ==> AwardPunish.drl 含规则组 award\_punish
  5. ==> TotalRule.drl 含规则组 sum\_salary

组合方式:

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

  1. ---> sum\_salary ---> \[end\]

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

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

四、详细设计

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

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

  1. eduInfo , resume , annualExam, awardPunish 均为 String ,
  2. basic\{duty,bonus, total\}\_salary , percent 作为 double 类型。

五、规则文件及规则流

  1. EduInfoRule.drl :

package myrules;

import sample.Employ;

rule “Bachelor”

  1. ruleflow-group "basic\_salary"

when

emp: Employ(eduInfo == “bachelor” );

then

System.out.println( “exec rule Bachelor … “ );

emp.setBasicSalary(1500);

end

rule “Master”

  1. ruleflow-group "basic\_salary"

when

emp: Employ(eduInfo== “master” )

then

System.out.println( “exec rule Master … “ );

emp.setBasicSalary(2500);

end

  1. Resume.drl

package myrules

import sample.Employ;

rule “Technician”

  1. ruleflow-group "duty\_salary"

when

emp: Employ(resume== “tech” )

then

System.out.println( “exec rule Technician … “ );

emp.setDutySalary(2000);

end

rule “Manager”

  1. ruleflow-group "duty\_salary"

when

emp: Employ(awardPunish== “manager” )

then

System.out.println( “exec rule manager … “ );

emp.setDutySalary(4500);

end

  1. BonusRule.drl

package myrules

import sample.Employ;

rule “Excellent”

  1. ruleflow-group "bonus\_salary"

when

emp: Employ(annualExam== “excellent” )

then

System.out.println( “exec rule Excellent … “ );

emp.setBonus(1000*1.0);

end

rule “Good”

  1. ruleflow-group "bonus\_salary"

when

emp: Employ(annualExam== “good” )

then

System.out.println( “exec rule Good … “ );

emp.setBonus(1000*0.9);

end

rule “Common”

  1. ruleflow-group "bonus\_salary"

when

emp: Employ(annualExam== “common” )

then

System.out.println( “exec rule Common … “ );

emp.setBonus(1000*0.6);

end

rule “failing”

  1. ruleflow-group "bonus\_salary"

when

emp: Employ(annualExam== “failing” )

then

System.out.println( “exec rule failing … “ );

emp.setBonus(1000*0.0);

end

  1. AwardPunish.drl

package myrules

import sample.Employ;

rule “Award”

  1. ruleflow-group "award\_punish"

when

emp: Employ(awardPunish== “award” )

then

System.out.println( “exec rule Award … “ );

emp.setPercent(1.10);

end

rule “Punishment”

  1. ruleflow-group "award\_punish"

when

emp: Employ(awardPunish== “punish” )

then

System.out.println( “exec rule Punishment … “ );

emp.setPercent(0.90);

end

rule “None”

  1. ruleflow-group "award\_punish"

when

emp: Employ(awardPunish== “none” )

then

System.out.println( “exec rule None … “ );

emp.setPercent(1.00);

end

  1. TotalRule.drl

package myrules

import sample.Employ;

rule “Total”

ruleflow-group “sum_salary”

when

emp: Employ()

then

System.out.println( “exec rule Total … “ );

double total = emp.getBasicSalary() + emp.getDutySalary() +

  1. emp.getBonus();

emp.setTotalSalary(total*emp.getPercent());

end

  1. 创建规则流文件 simple.rf :

<?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” /> Java Drools5.1 规则流基础【示例】 -  大雨 - 大雨的博客
<?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />

注意:

  1. \[1\] Split 结点类型为 OR ,约束选择 always true. 表示选择其规则组中所有符合事实的规则进行并发执行;
  2. \[2\] Join 结点类型为 AND ,表示当且进当上述规则组均执行完毕后,才执行后面的规则或进程。

Java Drools5.1 规则流基础【示例】 -  大雨 - 大雨的博客

六、测试代码:

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 ;

// getter/setter methods

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) {

  1. t.printStackTrace();

}

}

private static KnowledgeBase readKnowledgeBase() throws Exception {

KnowledgeBuilder kbuilder =

KnowledgeBuilderFactory.newKnowledgeBuilder();

kbuilder.add(ResourceFactory.newClassPathResource(“EduInfoRule.drl”), ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource(“ResumeRule.drl”), ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource(“BonusRule.drl”), ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource(“AwardPunish.drl”), ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource(“TotalRule.drl”), ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource(“salary.rf”), ResourceType.DRF);

KnowledgeBuilderErrors errors = kbuilder.getErrors();

if (errors.size() > 0) {

  1. for (KnowledgeBuilderError error: errors) \{
  2. System.err.println(error);
  3. \}
  4. throw new IllegalArgumentException("Could not parse knowledge.");

}

KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

return kbase;

}

}

  1. 测试结果:
  2. exec rule Technician ...
  3. exec rule Master ...

exec rule Good …

exec rule Award …

exec rule Total …

Basic Salary: 2500.0

Duty Salary: 2000.0

Bonus : 900.0

rate : 1.1

Total Salary: 5940

七、总结

Java drools 规则流基础:

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

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

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

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

下一步:

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

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

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

【 4 】用户自定义规则;

发表评论

表情:
评论列表 (有 0 条评论,450人围观)

还没有评论,来说两句吧...

相关阅读