`
AngelAndAngel
  • 浏览: 236481 次
  • 性别: 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
  
分享到:
评论

相关推荐

    "基于MATLAB的综合图像去雾算法系统设计:融合多种算法的数字图像增强与GUI实现",基于MATLAB的图像去雾综合系统设计:算法与数字图像处理的结合,包含GUI界面与多算法优化研究,基于matla

    "基于MATLAB的综合图像去雾算法系统设计:融合多种算法的数字图像增强与GUI实现",基于MATLAB的图像去雾综合系统设计:算法与数字图像处理的结合,包含GUI界面与多算法优化研究,基于matlab的去雾算法综合系统设计 【图像去雾】基于图像增强,数字图像处理,GUI设计。 功能:系统综合了目前常用的所有图像去雾的算法,包括全局直方图增强算法,局部直方图增强算法,Retinex单尺度算法,Retinex多尺度算法和暗通道先验去雾算法。 代码结构清晰,含有注释,运算速度快,可扩展。 ,包远程调试(第069期) ,基于Matlab;去雾算法综合系统设计;图像增强;数字图像处理;GUI设计;全局直方图增强算法;局部直方图增强算法;Retinex单尺度算法;Retinex多尺度算法;暗通道先验去雾算法;代码结构清晰;注释完整;运算速度快;可扩展;包远程调试。,MATLAB综合去雾算法系统设计

    "基于Matlab的手写数字识别程序(编号153):含GUI界面、神经网络算法及运行操作视频","基于Matlab的手写数字识别程序(编号153):含GUI界面、神经网络算法及操作视频",手写数字识别

    "基于Matlab的手写数字识别程序(编号153):含GUI界面、神经网络算法及运行操作视频","基于Matlab的手写数字识别程序(编号153):含GUI界面、神经网络算法及操作视频",手写数字识别Matlab程序含GUI界面 手写数字识别Matlab包含GUI界面,神经网络算法 这个程序是读取本地的图片,在图片中选择区域,然后裁切和识别。 程序已经训练好了,对于自带的图片识别效果最好。 程序经过多次测试,包成功运行,附带运行操作视频。 程序不。 程序编号:153 ,手写数字识别; Matlab程序; GUI界面; 神经网络算法; 图片读取; 图片裁切; 识别效果; 运行视频; 程序编号153,手写数字识别-Matlab神经网络GUI程序编号153

    【毕业设计】微信小程序优惠券商城(淘宝客、多多客),集成领券、信用返现、活动奖励、购物补贴、多级分销等功能,支持淘宝、拼多多、京东、唯品会、蘑菇街_pgj.zip

    【毕业设计】微信小程序优惠券商城(淘宝客、多多客),集成领券、信用返现、活动奖励、购物补贴、多级分销等功能,支持淘宝、拼多多、京东、唯品会、蘑菇街_pgj

    Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文档详述了一个基于 Matlab 平台实现的 GA-LSSVM(遗传算法优化最小二乘支持向量机)多输入单输出回归预测项目。该项目首先介绍了回归分析的需求及其面临的挑战,随后提出了将遗传算法与 LSSVM 结合的方法来优化回归模型,解决了 LSSVM 模型对参数选择的依赖,提高预测精度。具体实现步骤包括数据预处理、参数优化、LSSVM 模型构建、模型训练与评估等,并附有详细的程序设计和 GUI 实现代码。文中还展示了 GA-LSSVM 在多种应用场景中的优越性能,如工业生产、金融市场、环境监测、医疗诊断等。通过实际数据实验,验证了模型的有效性和优越性。 适合人群:从事数据分析、机器学习及相关领域的研究人员和工程师,特别是关注高精度回归预测的研究者或从业者。 使用场景及目标:此资源适用于需要精准回归预测的实际工程项目或科研活动中,如预测股价波动、监控设备状态、评估医疗健康指标等。目的是提高现有模型的泛化能力,自动优化参数选择,提升预测准确度并适应多样化输入数据。 其他说明:项目代码结构清晰,附带详细的说明文档和示例,方便理解和二次开发。同时提供了多种优化策略以应对不同类型的数据和场景限制。文中提到的模型具有良好的可扩展性,未来可以通过与其他先进技术如深度学习集成进一步改善预测效果。

    电气控制领域研究:基于超局部模型与扩张状态观测器的永磁同步电机无模型预测控制及其在IEEE TIE仿真复现与SCI一区Top期刊的应用,基于IEEE TIE仿真的电气控制技术:无模型预测控制在永磁同

    电气控制领域研究:基于超局部模型与扩张状态观测器的永磁同步电机无模型预测控制及其在IEEE TIE仿真复现与SCI一区Top期刊的应用,《基于IEEE TIE仿真的电气控制技术:无模型预测控制在永磁同步电机中的应用》,#电气控制 SCI一区top期刊,IEEE TIE仿真复现 基于超局部模型扩张状态观测器的永磁同步电机无模型预测控制 关键词 无模型预测控制 扩张状态观测器ESO 超局部模型PMSM ,无模型预测控制; 扩张状态观测器ESO; 超局部模型; 永磁同步电机PMSM; SCI一区top期刊; IEEE TIE仿真复现,"SCI一区期刊中永磁同步电机无模型预测控制研究,采用超局部模型与扩张状态观测器ESO技术"

    泵站智能恒压供水控制系统(三用一备)-基于YH42控制核心的昆仑通态界面监控系统 ,泵站智能恒压供水系统:三用一备YH42控制方案与设备配置,泵站恒压供水控制(三用一备)YH42 1.触摸屏:昆仑通态

    泵站智能恒压供水控制系统(三用一备)-基于YH42控制核心的昆仑通态界面监控系统。,泵站智能恒压供水系统:三用一备YH42控制方案与设备配置,泵站恒压供水控制(三用一备)YH42 1.触摸屏:昆仑通态 7062 串口通讯 MCGS软件打开 2.PLC西门子S7-200 226CN,扩展模块 EM235四块 每块带四路AI一路AO EM223一块 8入8出继电器输出 3.现场仪表 压力传感器0-1.6MPa (量程暂时) 4-20MA 4.变频器:艾克特 技术资料见附件 变频器模拟输入输出信号类型(因距离较远) 选电流信号 5.电动阀控制图纸 电动阀要求阀门开关信号(DO),开到位信号、关到位信号 6.带手自动切,手动:变频本地控制面板控制 自动:PLC控制 7.变频柜要提供运行状态信号(Di)、手自动切信号(Di)、故障状态信号(Di)、模拟量输入信号(AI)和模拟量输出信号(AO)、变频器启停信号(Do) 8.水库液位(超声波):4-20MA 0-8m(量程暂时)2台 9.现场变频柜打到自动后(现场变频柜手自动是指打到手动只能在盘上控制,打到自动在触摸屏可以控制),在触摸屏上还

    基于OpenCV和Python的人脸识别系统 2024免费JAVA毕设

    2024免费毕业设计成品,包括源码+数据库+往届论文资料,附带启动教程和安装包。 启动教程:https://www.bilibili.com/video/BV1jKDjYrEz1 技术栈:Vue.js+SpringBoot+MySQL。 开发工具:Idea+VSCode。

    DeepSeek大模型在教育领域的应用实践与技术创新

    第一篇 从正常使用“满血版”开始 DeepSeek火了,官网却几乎“半身不遂”,除第一次能正常访问外,其他访问次数都得看“运气”。下面提供几种替代性解决方案,虽不是百分百解决问题,但至少目前情况属于较好的解决方案。 1.用APP 手机APP(download.deepseek.com/app)和DeepSeek的官网均提供满血版服务。官网界面简洁直观,功能一目了然而手机APP则更加灵活便捷,对于教师来说,都能随时随地开启备课之旅,充分利用碎片化时间,来记录灵感。尽管目前官网在高峰时段可能会出现繁忙状况,但手机APP的稳定性相对好一些。当然也可以安装纳米搜索,360的DeepSeek专线,目前测试很稳定,在App商店搜索“360纳米搜索”,找到“大模型”栏目,选用DeepSeek R1轻松体验。 2.硅基流动网站 硅基流动网站提供了满血版的DeepSeek R1,性能体验上跟官网不相上下。需要注意的是,直接对话的界面不会保存聊天记录,复制粘贴不太好用,且在使用过程中,当赠送的14元额度耗尽后,就需要进行充值。但对于追求个性化教学、愿意投入资源进行教学创新的教师来说

    PHPSDCMS红色系网络公司网站 v2.4.5.zip

    SDCMS红色系网络公司网站是基于SDCMS四合一企业网站管理系统开发的模板,适合企业站,带手机版。 SDCMS四网合一企业网站管理系统是一个以PHP+MySQL/Sqlite进行开发的四网合一网站源码。 SDCMS四网合一企业网站管理系统功能特点: 四网合一企业网站管理系统支持在线升级(支持跨版本)、插件在线安装、系统内置严格的过滤体系、可以有效应对安全检测报告。 四网合一: 电脑网站、手机站(数据同步、支持绑定域名)、小程序、公众号管理一个后台即可搞定。 双数据库引擎、运行环境全面: 同时支持Sqlite和Mysql两种数据库引擎,支持Php5.4 至 7.4版本安装使用。 灵活的扩展: 支持模型自定义、字段自定义、表单自定义、内容参数自定义,系统参数扩展。 特色功能: 支持城市分站、列表筛选、栏目绑定域名功能、内容同时发布到多个栏目等功能。 会员系统: 会员自定义阅读权限。支持会员分组、支持会员QQ一键登录、微信扫码登录、微信App自动登录等。 文章收费功能: 支持付费阅读功能、同时支持有阅读权限的用户免付费功能。 主流支付接口: 支付宝(PC站支付、手机站支付)微信(扫码支付

    test250211 dfgfdgdf dg dfg

    test250211 dfgfdgdf dg dfg

    DeepSeek 使用技巧,强烈建议收藏!.pdf

    DeepSeek 使用技巧,强烈建议收藏!.pdf

    (springboot+mysql) 校园运动会管理系统 ,包含数据库mysql+前端页面vue 毕业论文以及开题报告+答辩PPT

    (springboot+mysql) 校园运动会管理系统 ,包含数据库mysql+前端页面vue 毕业论文以及开题报告+答辩PPT

    木块识别数据集,正确识别率95.7%,yolov7pytorch格式标注(可用于统计木块数量)

    木块识别数据集,正确识别率95.7%,yolov7pytorch格式标注(可用于统计木块数量)

    MUC-数据结构课程设计:哈夫曼树构建及其编码译码实现方法与应用场景

    内容概要:本文档详细介绍了一种基于数据结构中的哈夫曼树实现字符频率统计、哈夫曼编码和译码的具体步骤。首先介绍哈夫曼树的基本概念和原理,接着讲解如何通过C++程序读取文件,提取出文本中各个字符出现的概率,进而按照概率大小构造二叉树——哈夫曼树。然后针对构建完毕的哈夫曼树,对每一个字符分配特定前缀编码(即哈夫曼编码)。在此基础上,进一步探讨了如何将一段英文文章转化为对应于哈夫曼编码序列,并可以将这段特殊的01序列还原为原始的文章。此外还提供了文件压缩扩展实验部分的简述。 适合人群:正在学习数据结构或有兴趣研究高效信息编码的学生、开发者和研究人员。 使用场景及目标:①学习哈夫曼树这一经典树形结构的特性和优点;②掌握哈夫曼编码的基础原理和技术手段,熟悉编码、解码操作的实际流程;③通过实战练习加强对于数据压缩的理解,体验理论联系实际的乐趣,培养解决现实生活中相关问题的能力。 其他说明:文中给出了完整的源码实现,并详细解析了各个关键环节的设计思路。同时附带了几组实验数据供读者检验自己编写的系统的性能优劣,有助于加深学员的知识记忆,提高他们的问题求解水平。并且通过课程设计方案中的任务分解,使参与者明

    【毕业设计】基于安卓Android房屋租赁系统app设计毕业源码案例设计.zip

    【毕业设计】基于安卓Android房屋租赁系统app设计毕业源码案例设计

    [程序系统GUI实现]MATLAB教室人数统计.zip

    本项目是自己做的设计,有GUI界面,完美运行,适合小白及有能力的同学进阶学习,大家可以下载使用,整体有非常高的借鉴价值,大家一起交流学习。该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。

    基于JAVA+SpringBoot+Vue+MySQL的学生竞赛管理系统 源码+数据库(高分毕设项目).zip

    项目已获导师指导并通过的高分毕业设计项目,可作为课程设计和期末大作业,下载即用无需修改,项目完整确保可以运行。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 技术组成 语言:java 开发环境:idea 数据库:MySql5.7以上 部署环境:maven 数据库工具:navicat

    【毕业设计】信息资源挖掘与可视化平台.zip

    【毕业设计】信息资源挖掘与可视化平台

    "基于StarCCM+的储能液冷系统热管理仿真教学视频:带热失控仿真计算,三个模型文件实战练习","基于StarCCM+的储能液冷系统热管理仿真教学视频:带热失控仿真计算与三个模型文件供练习的实践指南

    "基于StarCCM+的储能液冷系统热管理仿真教学视频:带热失控仿真计算,三个模型文件实战练习","基于StarCCM+的储能液冷系统热管理仿真教学视频:带热失控仿真计算与三个模型文件供练习的实践指南",储能热管理 基于starccm+ 储能液冷系统热管理仿真 带热失控仿真计算…… 教学视屏,三个模型文件供练习。 储能热管理 ,核心关键词:储能热管理;starccm+仿真;液冷系统热管理;热失控仿真计算;教学视屏;模型文件练习。,《基于Starccm+的储能液冷系统与热失控仿真教学视频》

    compat-libstdc++-33-3.2.3 el7 64位

    oracle11g及以后版本安装时需要该包

Global site tag (gtag.js) - Google Analytics