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 Mapitems; 10 private Map IdToItem; 11 private float total; 12 private Map favourable; 13 public Purchase(){ 14 items=new HashMap (); 15 IdToItem=new HashMap (); 16 favourable=new HashMap (); 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 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 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 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 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(); Mapmap=pur.getFavour(); Set 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。
推荐一个介绍的很好的 博客,介绍的比较详细。