比如一个需求是根据不同的年纪,性别等把人分为不同类别并按对应类别做相应的操作。通常的做法是欠套很多if-else,但这样降低了代码的易读性和可维护性。一种改进措施就是定义一堆的类型功能方法,每个方法接受年纪和性别做参数,此时当有新人数据进来时只要依次调用每个功能方法就能得出所以符合的类别。就这大大增加了代码的易读性和可维护性。
Drools就是这样的一个工具,它简化了工作让你不需要编写功能方法,只需要维护一个配置文件(你可以不用配置文件)。下面就是对Drools工具的学习。
测试:
1. 下载并解压Drools (binaries目录包括所有依赖jar包)
2. 新建Java Project;
3. 导入Drools包 (可添加一用户变量包括所有的Drools包)
4. JUnit一并导入
5. Drools的使用步骤
// Step#1: build the KnowledgeBuilder via factory KnowledgeBuilder kbuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); kbuilder.add(resource, ResourceType.DRL); if (kbuilder.hasErrors()) { System.out.println(kbuilder.getErrors()); return; } Assert.assertFalse(kbuilder.hasErrors()); // Step#2: build the KnowledgeBase from the builder KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); // Step#3: inster the factor into the session<pre name="code" class="java">StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.insert(new Message("Hello")); ksession.fireAllRules(); ksession.dispose();
package com.yquants.drools; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; import org.drools.KnowledgeBase; import org.drools.KnowledgeBaseFactory; import org.drools.builder.KnowledgeBuilder; import org.drools.builder.KnowledgeBuilderFactory; import org.drools.builder.ResourceType; import org.drools.io.Resource; import org.drools.io.ResourceFactory; import org.drools.runtime.StatefulKnowledgeSession; import org.junit.Assert; import org.junit.Test; public class DroolsMain { private static Map<String, KnowledgeBase> map = new HashMap<String, KnowledgeBase>(); private static KnowledgeBase getKnowledgeBase(String filename) { if (!map.containsKey(filename)) { cacheKnowledgeBase(ResourceFactory.newFileResource(filename), filename); } return map.get(filename); } private static KnowledgeBase getKnowledgeBase(String content, String name) { if (!map.containsKey(name)) { cacheKnowledgeBase( ResourceFactory.newByteArrayResource(content.getBytes()), name); } return map.get(name); } private static void cacheKnowledgeBase(Resource resource, String name) { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory .newKnowledgeBuilder(); kbuilder.add(resource, ResourceType.DRL); if (kbuilder.hasErrors()) { System.out.println(kbuilder.getErrors()); return; } Assert.assertFalse(kbuilder.hasErrors()); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); map.put(name, kbase); } @Test public static void testWithDrlFile() throws Exception { final String filename = "rules/Game.drl"; KnowledgeBase kbase = getKnowledgeBase(filename); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.insert(new Message("Hello")); ksession.fireAllRules(); ksession.dispose(); } @Test public static void testGlobalVar() throws Exception { final String filename = "rules/Game.drl"; KnowledgeBase kbase = getKnowledgeBase(filename); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); List<BigDecimal> list = new java.util.ArrayList<BigDecimal>(); ksession.setGlobal("list", list); ksession.insert(new BigDecimal(1)); ksession.fireAllRules(); ksession.insert(new BigDecimal(-1)); ksession.fireAllRules(); ksession.dispose(); Assert.assertFalse(list.isEmpty()); for(BigDecimal bd: list) System.out.println(bd); } @Test public static void testWithInternalRule() throws Exception { StringBuilder sb = new StringBuilder() .append("package com.yquants.drools \n") .append("import com.yquants.drools.Message \n") .append("rule \"one\" \n").append("when \n") .append("eval(1==1) \n").append("eval(2==1) \n") .append("then \n") .append("System.out.println(\"internal rule[1==1]\"); \n") .append("end"); KnowledgeBase kbase = getKnowledgeBase(sb.toString(), "Internal Simple"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); ksession.insert("111"); ksession.fireAllRules(); ksession.dispose(); } public static void main(String[] args) throws Exception { Method[] methods = DroolsMain.class.getMethods(); Object[] params = null; for (Method m : methods) if (m.isAnnotationPresent(Test.class)) m.invoke(null, params); } }
完整源代码可见GitHub: https://github.com/yquants/JavaTutorial/tree/master/DroolsTest
运行环境:
JDK: 1.6
OS: Windows XP
IDE: Eclipse Juno Release
Drools: 6.3.0
参考:
http://docs.jboss.org/drools/release/6.3.0.Final/drools-docs/html_single/index.html#wb.QuickStart