`
AngelAndAngel
  • 浏览: 230511 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

drools实现自定义业务规则

阅读更多
   最近做财务相关的积分规则,由于这个功能以后涉及到方方面面,所以想尽可能做的可维护,可扩展,平台其他人调用起来更加方便,联想到财务相关的功能会更多的规则配置,在这里打算用drools规则引擎来实现。
   规则引擎说起来比较简单,当你的功能有很多未知条件需要判断或需要遵循很多业务规则时,就可以采用。
   首先看看规则文件大大致样子,
  
rule "testDrools"
   when 
     ...各种条件
   then
     ...执行业务
   end


看起来比较像if else,但是切忌,我们应该用一个业务人员的视角而不是一个程序员的视角来看规则文件,否则你会进入很多误区。
当多个工作对象进入规则引擎时,它可以根据多个条件同时判断,并且执行不同的业务代码。

下面有个场景,看看如何把规则引擎应用其中。
假如现在有两组数据对象,分别是现金流数据和账户数据,我们需要根据某个账户在某段时间内的现金流动状况来给账户计算余额。
首先新建现金流对象,账户对象,时间查询对象,分别如下(省去getter setter)
public class CashFlow {

	private Date date;
	private double amount;
	private String type;
	private long accountNo;


}

public class Account {

	private long accountNo;
	private double blance;
}

public class AccountPeriod {

	private Date start;
	private Date end;

}


我们的目的是根据传入的AccountPeriod对象和一系列CashFlow,Account对象来自动计算出每个Account对象的blance。

规则文件应该如下编写:
package org.drools.examples.cashflow
 
import org.drools.myTest.cashflow.Account;
import org.drools.myTest.cashflow.AccountPeriod;
import org.drools.myTest.cashflow.CashFlow;

rule "CREDIT"
when
 $ap:AccountPeriod()
 $acc:Account($accountNo:accountNo)
 CashFlow(type=="CREDIT",accountNo==$accountNo,date>=$ap.start && <=$ap.end,$amount:amount)
 then
 $acc.setBlance($acc.getBlance()+$amount);
 System.out.println("借入");
 end


rule "DEBITS"
when
 $ap:AccountPeriod()
 $acc:Account($accountNo:accountNo)
 CashFlow(type=="DEBIT",accountNo==$accountNo,date>=$ap.start && <=$ap.end,$amount:amount)
 then
 $acc.setBlance($acc.getBlance()-$amount);
  System.out.println("借出");
 end


drl规则文件引入包的语句和java类似,重点在下面。
首先创建规则,名为“CREDIT”,when里面是条件,冒号是赋值,以便下文使用,"==" ">=" "<="等符号的使用都和java类似。所以这个条件的意思是:
当传入的对象里面有AccountPeriod(并赋值到$ap),并且存在账户信息(并把accountNo赋值到$accountNo),并且存在现金流信息(并符合各属性的值的匹配),那么执行余额的增加。
规则DEBITS的逻辑差不多。
   编写引擎的编译及部署代码,如下
// KnowledgeBuilder用来在业务代码中收集已经编写好的规则,然后对这些规则文件进行编译,最终产生
		// 一批编译好的规则包(KnowledgePackage)给其他的应用程序使用
		final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
				.newKnowledgeBuilder();

		// 解析并且编译规则文件
		kbuilder.add(ResourceFactory.newClassPathResource("cashflow.drl",
				CashFlowTestMain.class), ResourceType.DRL);

		// 打出错误
		if (kbuilder.hasErrors()) {
			System.out.println(kbuilder.getErrors().toString());
			throw new RuntimeException("Unable to compile \"cashflow.drl\".");
		}

		// 得到编译后的包
		final Collection<KnowledgePackage> pkgs = kbuilder
				.getKnowledgePackages();

		// 部署到一个知识库
		// KnowledgeBase是用来收集应用当中知识定义的知识库对象,在一个KnowledgeBase当中,可以包含普通的规则(rule)
		// 规则流(rule flow),函数定义(function),用户自定义对象(type model),
		final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(pkgs);


规则引擎相当于一个容器,我们需要通过一个管道跟这个容器连起来,这个管道就是会话,新建一个有状态的会话:
//开启有状态会话
		final StatefulKnowledgeSession ksession = kbase
				.newStatefulKnowledgeSession();

ksession 对象的insert方法可以把对象放入工作区(容器),让规则引擎来处理。下面新建几条测试数据:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		/** ******************第一条记录************************* */
		CashFlow cf0 = new CashFlow();
		String time0 = "2010-01-12";
		cf0.setDate(sdf.parse(time0));
		cf0.setAmount(100);
		cf0.setType("CREDIT");
		cf0.setAccountNo(1);
		ksession.insert(cf0);

		CashFlow cf1 = new CashFlow();
		String time1 = "2010-02-02";
		cf1.setDate(sdf.parse(time1));
		cf1.setAmount(200);
		cf1.setType("DEBIT");
		cf1.setAccountNo(1);
		ksession.insert(cf1);

		CashFlow cf2 = new CashFlow();
		String time2 = "2010-05-18";
		cf2.setDate(sdf.parse(time2));
		cf2.setAmount(50);
		cf2.setType("CREDIT");
		cf2.setAccountNo(1);
		ksession.insert(cf2);

		CashFlow cf3 = new CashFlow();
		String time3 = "2010-03-18";
		cf3.setDate(sdf.parse(time3));
		cf3.setAmount(75);
		cf3.setType("CREDIT");
		cf3.setAccountNo(1);
		ksession.insert(cf3);

		Account acc = new Account();
		acc.setAccountNo(1);
		acc.setBlance(0);
		ksession.insert(acc);

		/** ******************第二条记录************************* */

		CashFlow cf0_else = new CashFlow();
		String time0_else = "2010-01-12";
		cf0_else.setDate(sdf.parse(time0_else));
		cf0_else.setAmount(150);
		cf0_else.setType("CREDIT");
		cf0_else.setAccountNo(2);
		ksession.insert(cf0_else);

		CashFlow cf1_else = new CashFlow();
		String time1_else = "2010-02-02";
		cf1_else.setDate(sdf.parse(time1_else));
		cf1_else.setAmount(500);
		cf1_else.setType("DEBIT");
		cf1_else.setAccountNo(2);
		ksession.insert(cf1_else);

		CashFlow cf2_else = new CashFlow();
		String time2_else = "2010-05-18";
		cf2_else.setDate(sdf.parse(time2_else));
		cf2_else.setAmount(50);
		cf2_else.setType("CREDIT");
		cf2_else.setAccountNo(2);
		ksession.insert(cf2_else);

		CashFlow cf3_else = new CashFlow();
		String time3_else = "2010-03-18";
		cf3_else.setDate(sdf.parse(time3_else));
		cf3_else.setAmount(75);
		cf3_else.setType("CREDIT");
		cf3_else.setAccountNo(2);
		ksession.insert(cf3_else);

		Account acc_else = new Account();
		acc_else.setAccountNo(2);
		acc_else.setBlance(0);
		ksession.insert(acc_else);

                  /* 查询条件 */
		AccountPeriod ap = new AccountPeriod();
		String start = "2009-05-06";
		String end = "2012-02-25";
		ap.setStart(sdf.parse(start));
		ap.setEnd(sdf.parse(end));
		ksession.insert(ap);

                   // 触发所有规则执行
		ksession.fireAllRules();


		// 一定要释放
		ksession.dispose();


至此,规则已全部启动,为了测试,打印这两个账户的余额信息:
System.out.println(acc.getAccountNo() + " : " + acc.getBlance());
		System.out.println(acc_else.getAccountNo() + " : "
				+ acc_else.getBlance());

结果为:
借出
借入
借入
借入
借出
借入
借入
借入
1 : 25.0
2 : -225.0


By 阿飞哥 转载请说明
腾讯微博:http://t.qq.com/duyunfeiRoom
新浪微博:http://weibo.com/u/1766094735
  
分享到:
评论

相关推荐

    springboot集成drools实现重新加载规则

    springboot集成drools实现重新加载规则

    drools实现将规则和业务的区分

    spring boot和drools结合,实现将规则和业务的区分。通过workbeach编写规程文件,实现动态的更新规则

    drools整合apollo实现动态规则引擎

    drools整合apollo实现动态规则引擎,可以在不停服的情况下动态调整规则。无需数据库等存储,自动推送

    drools动态生成规则文件

    drools动态生成规则文件

    Drools规则引擎从入门到精通

    1 Drools简介1.1 Drools的作用1.2 使用规则引擎的优势1.3 规则引擎应用场景2 Drools初体验2.1 构建项目2.2 案例描述 2.3 代码实现3 Drools语法介绍3.1 规则文件的组成3.2 规则体语法结构3.3 Pattern模式匹配 ...

    Drools规则引擎Drools规则引擎

    Drools是Jboss公司旗下一款开源的规则引擎,它完整的实现了Rete 算法;提供了强大的Eclipse Plugin开发支持; 通过使用其中的DSL(Domain Specific Language),可以实现用自然语言方式来描述业务规则,使得业务分析...

    Drools规则引擎实现原理及示例

    Drools规则引擎是一种嵌套在应用程序中的组件, 是用Java...它实现了将业务规则从程序代码忠分离出来,规则引擎使用特定的语法编写业务规则,规则引擎可以接受数据输入、解释业务规则,并根据业务规则做出相应的决策。

    使用 Drools 规则引擎实现业务逻辑

    使用规则引擎可以通过降低实现复杂业务逻辑的组件的复杂性,降低应用程序的维护和可扩展性成本。这篇更新的文章展示如何使用开源的 Drools 规则引擎让 Java™ 应用程序更适应变化。Drools 项目引入了一个新的本地...

    规则引擎Drools入门实战案例

    Drools入门案例 ...6、使用规则引擎提供的规则编辑工具,使复杂的业务规则实现变得的简单 对于一些存在比较复杂的业务规则并且业务规则会频繁变动的系统比较适合使用规则引擎,如下: 1、风险控制系统-

    Drools 业务规则管理系统 BRMS

    01-规则引擎Drools-问题引出 ---01-课程介绍.mp4 ---02-问题引出(业务规则说明).mp4 ---03-问题引出(传统实现方式).mp4 02-规则引擎Drools-规则引擎概述 ---01-规则引擎概述(什么是规则引擎).mp4 ---02-规则...

    Drools规则引擎实现示例

    使用Java开源框架Drools实现的一个示例 可以直接运行

    Drools规则引擎介绍

    Drools是Jboss公司旗下...最新版本Drools5提供了基于WEB的BRMS——Guvnor,Guvnor提供了规则管理的知识库,通过它可以实现规则的版本控制,及规则的在线修改与编译,使得开发人员和系统管理人员可以在线管理业务规则。

    JAVA规则引擎JBOSS RULES(DROOLS 6.5) 动态规则

    1.基于JBOSS RULES(DROOLS) 6.5 开发 2.JAR包精简后只有20个 10.9M 3.动态规则 项目中使用需自己修改为从数据库加载规则

    Drools7 + Springboot2 动态更新规则

    Drools7 + Springboot2 动态更新规则。 规则存储到数据库MYSQL,动态从数据库中获取规则进行加载。 运行前请自行修改MYSQL配置

    基于Java注解的Drools业务规则开发框架设计实现.pdf

    基于Java注解的Drools业务规则开发框架设计实现.pdf

    drools文档教程-规则引擎文档

    drools文档教程-规则引擎文档

    Drools5.x 规则引擎开发教程

    Drools5.x 规则引擎开发教程 比较详细的介绍了规则引擎的作用 以及基础知识 规则编写案例 开发案例

Global site tag (gtag.js) - Google Analytics