一、为什么要使用规则引擎
有三天营运想弄一个积分策略,估算额外积分金额,规则如下:
订单原价金额100以下,不加分;
100-500加100分;
500-1000加500分;
1000以上加1000分;
传统java业务实现如下:
public class JavaScoreExample {
public static void main(String[] args) throws Exception {
List orderList = getInitData();
for (int i=0; i 100 && order.getAmout() <= 500){
order.setScore(100);
addScore(order);
}else if(order.getAmout() > 500 && order.getAmout() <= 1000){
order.setScore(500);
addScore(order);
}else{
order.setScore(1000);
addScore(order);
}
}
}
private static void addScore(Order o){
System.out.println("用户" + o.getUser().getName() + "享受额外增加积分: " + o.getScore());
}
private static List getInitData() throws Exception {
List orderList = new ArrayList();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
{
Order order = new Order();
order.setAmout(80);
order.setBookingDate(df.parse("2015-07-01"));
User user = new User();
user.setLevel(1);
user.setName("Name1");
order.setUser(user);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(200);
order.setBookingDate(df.parse("2015-07-02"));
User user = new User();
user.setLevel(2);
user.setName("Name2");
order.setUser(user);
orderList.add(order);
}
return orderList;
}
}
这时侯因为市场需求变化,又要调整规则时侯,则又要进行业务层面的代码更改、部署,非常麻烦。
假如我们可以把决策规则从应用程序中分离下来,将对系统提供很大的便利!
由此,诞生了规则引擎!如下如所示:
规则引擎优势:
对系统的使用人员
把业务策略(规则)的创建、修改和维护的权力交给业务总监
提升业务灵活性
强化业务处理的透明度,业务规则可以被管理
降低对IT人员的依赖程度
防止将来升级的风险
对IT开发人员
简化系统构架,优化应用
提升系统的可维护性和维护成本
便捷系统的整合
降低编撰“硬代码”业务规则的成本和风险
目前市面上比较热门的规则引擎有几款:
IlogJRules是最有名的商用BRMS;
Drools是最活跃的开源规则引擎;
Jess是Clips的java实现,就如JRuby之于Ruby,是AI系的代表;
VisualRules(旗正规则引擎)国外商业规则引擎品牌。
本文将注重介绍Drools。
二、什么是Drools
Drools是一个基于CharlesForgy’s的RETE算法的,便于访问企业策略、易于调整以及便于管理的开源业务规则引擎,符合业内标准,速率快、效率高。
业务剖析师人员或初审人员可以借助它轻松查看业务规则,因而检验是否已编码的规则执行了所需的业务规则。
Drools是用Java语言编撰的开放源码规则引擎,使用Rete算法对所编撰的规则求值。Drools准许使用申明形式抒发业务逻辑。可以使用非XML的本地语言编撰规则,因而易于学习和理解。而且,还可以将Java代码直接嵌入到规则文件中,这令Drools的学习愈加吸引人。
三、Drools实战
下边我们将使用drools把一部份中估算额外积分金额规则从代码中剥离下来:
github传送门::
1、引入pom文件
org.drools
drools-core
7.0.0.Final
org.drools
drools-compiler
7.0.0.Final
org.drools
drools-decisiontables
7.0.0.Final
org.drools
drools-templates
7.0.0.Final
org.kie
kie-api
7.0.0.Final
2、在src/main/resources/ruls新建Point-rules.drl规则文件:
package rules
import com.neo.drools.entity.Order
rule "zero"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout <= 100)
then
$s.setScore(0);
update($s);
end
rule "add100"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 100 && amout <= 500)
then
$s.setScore(100);
update($s);
end
rule "add500"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 500 && amout <= 1000)
then
$s.setScore(500);
update($s);
end
rule "add1000"
no-loop true
lock-on-active true
salience 1
when
$s : Order(amout > 1000)
then
$s.setScore(1000);
update($s);
end
3、src/main/resources/META-INF新建配置文件kmodule.xml:
4、最后在程序中调用规则,即可实现:
/**
* 计算额外积分金额 规则如下: 订单原价金额
* 100以下, 不加分
* 100-500 加100分
* 500-1000 加500分
* 1000 以上 加1000分
*
* @param args
* @throws Exception
*/
public static final void main(final String[] args) throws Exception{
// KieServices is the factory for all KIE services
KieServices ks = KieServices.Factory.get();
// From the kie services, a container is created from the classpath
KieContainer kc = ks.getKieClasspathContainer();
execute( kc );
}
public static void execute( KieContainer kc ) throws Exception{
// From the container, a session is created based on
// its definition and configuration in the META-INF/kmodule.xml file
KieSession ksession = kc.newKieSession("point-rulesKS");
List orderList = getInitData();
for (int i = 0; i < orderList.size(); i++) {
Order o = orderList.get(i);
ksession.insert(o);
ksession.fireAllRules();
// 执行完规则后, 执行相关的逻辑
addScore(o);
}
ksession.dispose();
}
private static void addScore(Order o){
System.out.println("用户" + o.getUser().getName() + "享受额外增加积分: " + o.getScore());
}
private static List getInitData() throws Exception {
List orderList = new ArrayList();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
{
Order order = new Order();
order.setAmout(80);
order.setBookingDate(df.parse("2015-07-01"));
User user = new User();
user.setLevel(1);
user.setName("Name1");
order.setUser(user);
order.setScore(111);
orderList.add(order);
}
{
Order order = new Order();
order.setAmout(200);
order.setBookingDate(df.parse("2015-07-02"));
User user = new User();
user.setLevel(2);
user.setName("Name2");
order.setUser(user);
orderList.add(order);
}
return orderList;
}
结果输出:
总结:
应用场景
·为提升效率,管理流程必须手动化,虽然现代商业规则异常复杂。
·市场要求业务规则时常变化,系统必须根据业务规则的变化快速、低成本的更新。
·为了快速、低成本的更新,业务人员应能直接管系统中的规则,不须要程序开发人员参与。
作用与优点:
·将业务规则与业务系统分离,前馈合;
·实现自然语言描述规则逻辑,业务人员便于理解;
·可视化的规则订制、审批、查询及管理;
·能有效的提升实现复杂逻辑的代码的可维护性;
·应付特殊状况,即顾客一开始没有提及要将业务逻辑考虑在内;
·符合组织对敏捷或迭代开发过程的使用;
下文将继续讲解,drools基础句型,以及使用springboot集成drools企业级开发,并实现热加载规则!
传送门:《规则引擎Drools之springboot集成、热加载》