规则引擎Drools 之 初识drools

一、为什么要使用规则引擎

 有一天运营想弄一个积分策略,计算额外积分金额 ,规则如下:

订单原价金额 100以下, 不加分;
100-500 加100分;
500-1000 加500分;
1000 以上 加1000分;

传统java业务实现如下:

public class JavaScoreExample {
      
    public static void main(String[] args) throws Exception {  
          
        List<Order> orderList = getInitData();
        for (int i=0; i<orderList.size(); i++){  
            Order order = orderList.get(i);  
            if (order.getAmout() <= 100){  
                order.setScore(0);  
                addScore(order);  
            }else if(order.getAmout() > 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<Order> getInitData() throws Exception {  
        List<Order> orderList = new ArrayList<Order>();
        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开发人员

简化系统架构,优化应用
提高系统的可维护性和维护成本
方便系统的整合
减少编写“硬代码”业务规则的成本和风险

目前市面上比较热门的规则引擎有几款:

Ilog JRules 是最有名的商用BRMS;
Drools 是最活跃的开源规则引擎;
Jess 是Clips的java实现,就如JRuby之于Ruby,是AI系的代表;
 Visual Rules(旗正规则引擎)国内商业规则引擎品牌。

本文将着重介绍Drools。

二、什么是Drools

Drools 是一个基于Charles Forgy’s的RETE算法的,易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。

业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。

Drools 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。Drools允许使用声明方式表达业务逻辑。可以使用非XML的本地语言编写规则,从而便于学习和理解。并且,还可以将Java代码直接嵌入到规则文件中,这令Drools的学习更加吸引人。

三、Drools 实战 

下面我们将使用drools 把一部分中计算额外积分金额 规则从代码中剥离出来:

github 传送门:https://github.com/vincent9309/drools

 1、引入pom文件

        <dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
			<version>7.0.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-compiler</artifactId>
			<version>7.0.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-decisiontables</artifactId>
			<version>7.0.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-templates</artifactId>
			<version>7.0.0.Final</version>
		</dependency>

		<dependency>
			<groupId>org.kie</groupId>
			<artifactId>kie-api</artifactId>
			<version>7.0.0.Final</version>
		</dependency>

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:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://www.drools.org/xsd/kmodule">

    <kbase name="point-rulesKB" packages="rules">
        <ksession name="point-rulesKS"/>
    </kbase>

    <kbase name="HelloWorldKB" packages="rules">
        <ksession name="HelloWorldKS"/>
    </kbase>


</kmodule>

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<Order> 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<Order> getInitData() throws Exception {  
        List<Order> orderList = new ArrayList<Order>();
        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 集成、热加载》

发布了114 篇原创文章 · 获赞 207 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/wuzhiwei549/article/details/104813821