论坛首页 Java企业应用论坛

规则引擎 Drools 使用解析

浏览 16075 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-05-05  

   Drools 5 采用了原生的规则语言,那是一种非 XML 文本格式。在符号方面,这种格式是非常轻量的,它的应用非常简单。可以适用于比较复杂的业务逻辑,本例是用于计费系统的批价,粗略来说,有按次收费,按月收费,按照流量收费,又根据前提不同,使用不同的优惠策略,比如购买了某产品赠送800通话实践100分钟,又有可能根据当月实际使用天数赠送一定的通话时长。如此复杂场景使用规则引擎再好不过了,将动态的都用规则标识,模型里只存有静态数据。

  首先Drools 规则要卸载drl 的文件里,通过程序加载这个drl,然后才可以运算

 

  1. 引入jar包(maven 编译)

 

  <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>5.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-compiler</artifactId>
      <version>5.0.1</version>
    </dependency>

 2. 包装下drools

 

 

public class RuleRunner {
	
	public RuleRunner() {
    }
	private static final String RULES_FILE="rules/charge.drl";
	
	    public void runRules(Object[] facts){

	        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
	        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
	        System.out.println( "Loading file: " + RULES_FILE );
	        kbuilder.add( ResourceFactory.newClassPathResource( RULES_FILE,RuleRunner.class ),ResourceType.DRL );
	        if (kbuilder.hasErrors() ) {
	            throw new ServiceException("charge.drl is a invalid rule file!");
	        }
	        Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
	        kbase.addKnowledgePackages( pkgs );
	        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
	        for ( int i = 0; i < facts.length; i++ ) {
	            Object fact = facts[i];
	            System.out.println( "Inserting fact: " + fact );
	            ksession.insert( fact );
	        }
	        ksession.fireAllRules();
	    }
	}

 

 3. 调用这个封装进行异步的规则处理

 

 

 

 

 

 

 

Object[] facts={chargeRulesModel,chargePriceResult};
        new RuleRunner().runRules(facts);

 

 

 facts 就是要传入传出的对象。

 

  4. 一个规则的解析

#created on: 2010-4-26
package charge

#list any import classes here.
import java.math.BigDecimal;

rule "rule_800yz:be707 -2" #800月租费优惠 规则头注释
	when   #条件
		$chargeModel : ChargeRulesModel($pricePlan:pricePlan,$featureList:featureList,eval($pricePlan.getPricePlanMain().getRuleCode().equals("rule_800yz")),eval(String.valueOf($featureList.get("pp900_1000")).equals("10Express")))
		$chargeResult : ChargePriceResult()
	then    # 执行逻辑
	double price=$pricePlan.getCyclePolicy().getPrice();
	  int usage=(Integer)($featureList.get("pp900_61"));
	  int accountLength=(Integer)($featureList.get("pp900_59"));
	  int totalAccount=(Integer)($featureList.get("pp900_88"));
	  int preferValue= Integer.parseInt($pricePlan.getPreferentialPolicy().getPreferentValue());
	  ##总使用量-赠送量>账期     则取账期的使用量作为使用天数
	  if(totalAccount- preferValue>= accountLength){ #使用类似java语言的判断逻辑
	  	usage=  accountLength;
	  }else{
	  	usage = totalAccount- preferValue;
	  }
	  BigDecimal result=  new BigDecimal(price*usage/accountLength);
	  $chargeResult.setAmount(result);
	  System.out.println("800月租费优惠");
end

 主要包含注释,条件,要执行的业务,还可以写方法-也就相当于helper类,实际运行时会转化为java类,但是不建议这么写,你完全可以另外写个java类,这里调用就可以了。

 

    到这里就可以完成你的drools 应用了,具体原理下回分解

   发表时间:2010-05-06  
Drools规则引擎介绍.ppt

什么是规则引擎?
Drools规则引擎介绍
信用卡申请实例介绍
Drools实现信用卡申请规则
编写客户端测试信用卡申请规则
0 请登录后投票
   发表时间:2010-05-06  
看了之后还是不明白了。呵呵,
0 请登录后投票
   发表时间:2010-05-07  
以前用drools,在drl文件里加了很多function,写起来超难受。。。
0 请登录后投票
   发表时间:2010-05-07  
用过drolls,但总是一知半解,感觉不太符合JAVA程序编写习惯,总觉得很别扭!
0 请登录后投票
   发表时间:2010-05-07  
正在使用drools期待更多交流
0 请登录后投票
   发表时间:2010-05-07  
都不知道是什么, 最后那一堆代码看得蛋疼
0 请登录后投票
   发表时间:2010-05-07   最后修改:2010-05-07
我对规则引擎的理念也很感兴趣,但是联想到实际的工作场景,我发现Drools并没有想象中的完美,以下疑问请教众位大侠:

1.规则里面很多的判据不是直接就具备的,需要一些整理过程,那么这些整理过程到底是在Java类里面做还是在Drools规则里面做?举例子说:
规则如下:
如果用户购买的商品中有两个以上的A产品和一个B产品就打85折。
如果用户购买的商品中有两个以上的B产品,就打8折。

在实际开发中,我们会把用户准备购买的产品都放在一个列表中。
如果要应用规则引擎,直接以产品列表为“事实”是最理想的,但是以直接以产品列表为“事实”就需要在规则中插入Java代码,用来整理出产品A和产品B的数量。这样一来,整理产品列表的Java代码就脱离了Java的运行环境,调试起来比较困难。至于更复杂的一些业务规则,用Rule去实现岂不是很难阅读和理解?

如果我们不直接以产品列表为"事实",而已采购的产品A和B的数量为事实,那么在调用规则之前,就要在Java中整理产品列表,求出产品A和B的数量,然后将其作为“事实”调用规则。此种方案的缺点就是不够灵活。一旦规则变化了,需要纳入产品C的数量来作为打折的依据,那么既要修改Java中整理产品列表的代码,又要修改规则文件。这也是我们不愿意看到的场面!

2.所谓的“业务规则”和“业务逻辑”区别到底在哪?是不是所有业务逻辑都可以看做是“业务规则”?如果是这样,那么复杂的业务逻辑或者说复杂的业务规则用规则文件去编写是否合适?如何把握将哪些业务规则用规则引擎去实现的度?


3. 如果要推入工作内存的事实量较大,或者需要用到的规则量较大,规则引擎的性能可否满足要求呢?

4. “部门经理(角色)能够批准2天以内的请假,总经理(角色)可以批准2天以上的请假”,这样的规则算不算业务规则?这样的规则中,什么是事实,什么是结论?在工作流的场景下,我期望的是给出申请的请假天数,然后根据业务规则找出可以批准的角色,然后将工作任务发给该角色。那么规则引擎是否具有这样类似的查询功能呢?或者我该如何去实现?

0 请登录后投票
   发表时间:2010-05-07  
这么好的探讨主题,怎么没人感兴趣吗?
0 请登录后投票
   发表时间:2010-05-07  
不知道这家伙是做什么地,插不上嘴呀
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics