规则引擎drools

2014.11.07 实习的第一周

这一周leader分配给我的任务是调研jboss 的drools,然后写一个sample。原来从来没听说过规则引擎,感觉亚历山大啊!!!!

 

规则引擎

  先来一段百度百科

  规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。应用背景: 企业级管理者对企业IT系统的开发有着如下的要求:
  1.为提高效率,管理流程必须自动化,即使现代商业规则异常复杂。
  2.市场要求业务规则经常变化,IT系统必须依据业务规则的变化快速、低成本的更新。
  3.为了快速、低成本的更新,业务人员应能直接管理IT系统中的规则,不需要程序开发人员参与。
  举个栗子:我们现在维护一个电商网站,网站在特定的时间段,对特定的人群会有一些优惠,比如双十一满100减10元,积分到达100分的用户可以打九折,水果类商品满100减5元。。。。。。这些规则错综复杂,而且变化周期很短,可能有的活动只有几个小时,如果我们把这些业务逻辑直接写入到我们的代码中去,那么后期的维护,修改将是异常痛苦。
  所以我们有必要把我们的业务逻辑和我们的平台代码分离,以后有业务需求只需要更改我们的逻辑规则即可。
 
Drools
 drools是jboss 下的开源规则引擎,基于rete算法的java实现,利用drools我们可以轻松解决我们前面所说的问题。
  drools有Eclipse的插件,开发环境很容易搭建。
  用drools来构建一个规则引擎整体的模块应该是这样的:
 
  
写一个sample吧
首先是user 主要有id,积分,vip等级
 1 package com.bian.sample;
 2 
 3 public class User {
 4     private long user_id;
 5     private long user_score;
 6     private int vip_level;
 7     public User(){}
 8     public long getUserId(){
 9         return user_id;
10     }
11     
12     public void setUserId(long id){
13         this.user_id=id;
14     }
15     
16     public long getUserScore(){
17         return user_score;
18     }
19     
20     public void setUserScore(long score){
21         this.user_score=score;
22     }
23     
24     public int getVipLevel(){
25         return this.vip_level;
26     }
27     
28     public void setVipLevel(int level){
29         this.vip_level=level;
30     }
31 }

item 有id,价格,种类

 1 package com.bian.sample;
 2 
 3 public class Item {
 4     
 5     private final long item_id;
 6     private float item_price;
 7     private String item_category;
 8     
 9     public Item(long id){
10         this.item_id=id;
11     }
12     
13     public long getItemId(){
14         return this.item_id;
15     }
16     
17     public float getItemPrice(){
18         return this.item_price;
19     }
20     
21     public void setItemPrice(float price){
22         this.item_price=price;
23     }
24     
25     public String getItemCategory(){
26         return this.item_category;
27     }
28     
29     public void setItemCategoty(String cate){
30         this.item_category=cate;
31     }
32 }

一次购买行为

 1 package com.bian.sample;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 import java.util.Set;
 6 
 7 public class Purchase {
 8     private User user;
 9     private Map<Long,Integer> items;
10     private Map<Long,Item> IdToItem;
11     private float total;
12     private Map<String,Float> favourable;
13     public Purchase(){
14         items=new HashMap<Long,Integer>();
15         IdToItem=new HashMap<Long,Item>();
16         favourable=new HashMap<String,Float>();
17     }
18     
19     public User getUser(){
20         return user;
21     }
22     
23     public void setUser(User u){
24         this.user=u;
25     }
26     
27     public Map<Long,Integer> getItems(){
28         return this.items;
29     }
30     
31     public void addItem(Item item,int num){
32         this.IdToItem.put(item.getItemId(),item);
33         this.items.put(item.getItemId(), num);
34     }
35     
36     public float getCategotyTotal(String cate){
37         float t=0;
38         Set<Long> Ids=this.IdToItem.keySet();
39         for(Long id:Ids){
40             Item item=IdToItem.get(id);
41             if(item.getItemCategory().equals(cate)){
42                 int num=items.get(id);
43                 t+=num*item.getItemPrice();
44             }
45         }
46         return t;
47     }
48     
49     public float getTotal(){
50         Set<Long> Ids=this.IdToItem.keySet();
51         for(Long id:Ids){
52             Item item=IdToItem.get(id);
53             int num=items.get(id);
54             total+=num*item.getItemPrice();
55         }
56         return total;
57     }
58     
59     public void addFavour(String message,float num){
60         this.favourable.put(message, num);
61     }
62     
63     public Map<String,Float> getFavour(){
64         return this.favourable;
65     }
66 }

制定的规则:满200元-5,水果满100元-5,用户积分大于100分-5元,vip等级大于7-5元

package com.bian.sample

import com.bian.sample.Item;
import com.bian.sample.User;
import com.bian.sample.Purchase;
import com.bian.sample.DroolsSample;

rule "200-5"
	when
		p:Purchase(p.getTotal()>=200)
	then
		p.addFavour("200-5",5);
end

rule "fruit100-5"
	when
		p:Purchase(p.getCategotyTotal("fruit")>=100)
	then
		p.addFavour("fruit100-5",5);
end

rule "user score 100-5"
	when 
		p:Purchase(p.getUser().getUserScore()>=100)
	then
		p.addFavour("user score 100-5",5);
end

rule "Vip 7 -5"
	when 
		p:Purchase(p.getUser().getVipLevel()>=7)
	then
		p.addFavour("Vip 7 -5",5);
end

测试类:

package com.bian.sample;

import java.util.Map;
import java.util.Set;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class DroolsSample {
    public static void main(String[] args){
        KieServices ks=KieServices.Factory.get();
        KieContainer kc=ks.getKieClasspathContainer();
        KieSession kSession=kc.newKieSession("session-rules");
        User user=new User();
        user.setUserId(123);
        user.setUserScore(100);
        user.setVipLevel(10);
        Item item=new Item(1001);
        item.setItemPrice(10);
        item.setItemCategoty("fruit");
        Purchase pur=new Purchase();
        pur.setUser(user);
        pur.addItem(item, 10);
        kSession.insert(pur);
        kSession.fireAllRules();
        Map<String,Float> map=pur.getFavour();
        Set<String> set=map.keySet();
        for(String s:set){
            System.out.println(s+" "+map.get(s));
        }
    }
}

运行结果:

user score 100-5 5.0
fruit100-5 5.0
Vip 7 -5 5.0

drools 6.x 的API中KIE的部分很是迷惑人

KIE是jBoss里面一些相关项目的统称,下图就是KIE代表的一些项目,其中我们比较熟悉的就有jBPM和Drools。

这些项目都有一定的关联关系,并且存在一些通用的API,比如说涉及到构建(building)、部署(deploying)和加载(loading)等方面的,这些API就都会以KIE作为前缀来表示这些是通用的API。前面看到的一些KieServices、KieContainer、KieSession类就都是KIE的公共API。

 
 推荐一个介绍的很好的博客,介绍的比较详细。
 
 
 
 
 
 
 
 
 
 
posted on 2014-11-07 15:24  随风蔷薇  阅读(1829)  评论(0编辑  收藏  举报