ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲成人福利,男人的天堂久久精品,濑亚美莉一二区在线视频http://www.aygfsteel.com/clant/category/17974.htmlzh-cnFri, 02 Mar 2007 21:54:11 GMTFri, 02 Mar 2007 21:54:11 GMT60Java规则引擎工作原理å?qi¨¢ng)其应ç”?/title><link>http://www.aygfsteel.com/clant/articles/87951.html</link><dc:creator>BPM </dc:creator><author>BPM </author><pubDate>Fri, 15 Dec 2006 07:19:00 GMT</pubDate><guid>http://www.aygfsteel.com/clant/articles/87951.html</guid><wfw:comment>http://www.aygfsteel.com/clant/comments/87951.html</wfw:comment><comments>http://www.aygfsteel.com/clant/articles/87951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/clant/comments/commentRss/87951.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/clant/services/trackbacks/87951.html</trackback:ping><description><![CDATA[ <strong>æ‘?è¦?/strong> Java规则引擎是一¿UåµŒå…¥åœ¨Java½E‹åºä¸­çš„¾l„äšgåQŒå®ƒçš„ä“Q务是把当前提交给引擎的Java数据对象与加载在引擎中的业务规则˜q›è¡Œ‹¹‹è¯•和比对,‹È€‹z»é‚£äº›ç¬¦åˆå½“前数据状态下的业务规则,æ ÒŽ(gu¨©)®ä¸šåŠ¡è§„åˆ™ä¸­å£°æ˜Žçš„æ‰§è¡Œé€»è¾‘åQŒè§¦å‘应用程序中对应的操作ã€?<b>引言</b>目前åQŒJava½C‘ÖŒºæŽ¨åЍòq¶å‘展了(ji¨£n)一¿Uå¼•人注目的新技术——Java规则引擎åQˆRule EngineåQ‰ã€‚利用它?y¨­u)®±å¯ä»¥åœ¨åº”用¾pȝ»Ÿä¸­åˆ†¼›Õd•†ä¸šå†³½{–者的商业决策逻辑和应用开发者的技术决½{–,òq¶æŠŠ˜q™äº›å•†ä¸šå†³ç­–攑֜¨ä¸­å¿ƒ(j¨©)数据库或其他¾lŸä¸€çš„地方,让它们能在运行时可以动态地½Ž¡ç†å’Œä¿®æ”¹ï¼Œä»Žè€ŒäØ“(f¨´)企业保持灉|´»æ€§å’Œç«žäº‰åŠ›æä¾›æœ‰æ•ˆçš„æŠ€æœ¯æ”¯æŒã€?br /><b><br />规则引擎的原ç?br /></b><strong>1、基于规则的专家¾pȝ»ŸåQˆRBESåQ‰ç®€ä»?/strong>Java规则引擎èµähºäºŽåŸºäºŽè§„则的专家¾pȝ»ŸåQŒè€ŒåŸºäºŽè§„则的专家¾pȝ»Ÿåˆæ˜¯ä¸“å®¶¾pȝ»Ÿçš„其中一个分支。专家系¾lŸå±žäºŽäh工智能的范畴åQŒå®ƒæ¨¡ä»¿äººç±»çš„æŽ¨ç†æ–¹å¼ï¼Œä½¿ç”¨è¯•探性的æ–ÒŽ(gu¨©)³•˜q›è¡ŒæŽ¨ç†åQŒåÆˆä½¿ç”¨äººç±»èƒ½ç†è§£çš„æœ¯è¯­è§£é‡Šå’Œè¯æ˜Žå®ƒçš„æŽ¨ç†ç»“è®ºã€‚äØ“(f¨´)äº?ji¨£n)更深入åœîCº†(ji¨£n)è§£Java规则引擎åQŒä¸‹é¢ç®€è¦åœ°ä»‹ç»åŸÞZºŽè§„则的专家系¾lŸã€‚RBES包括三部分:(x¨¬)Rule BaseåQˆknowledge baseåQ‰ã€Working MemoryåQˆfact baseåQ‰å’ŒInference Engine。它们的¾l“构如下¾pȝ»Ÿæ‰€½Cºï¼š(x¨¬) <center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213335938787.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">å›? åŸÞZºŽè§„则的专家系¾lŸæž„成如å›?所½Cºï¼ŒæŽ¨ç†å¼•擎包括三部分:(x¨¬)模式匚w…å™¨ï¼ˆPattern MatcheråQ‰ã€è®®½E‹ï¼ˆAgendaåQ‰å’Œæ‰§è¡Œå¼•擎åQˆExecution EngineåQ‰ã€‚推理引擎通过军_®šå“ªäº›è§„则满èƒö事实或目标,òq¶æŽˆäºˆè§„则优先çñ”åQŒæ»¡­‘³äº‹å®žæˆ–目标的规则被加入议程。模式匹配器军_®šé€‰æ‹©æ‰§è¡Œå“ªä¸ªè§„则åQŒä½•时执行规则;议程½Ž¡ç†æ¨¡å¼åŒšw…å™¨æŒ‘选出来的规则的执行次序;执行引擎负责执行规则和其他动作。和人类的思维相对应,推理引擎存在两者推理方式:(x¨¬)演绎法(F(tu¨¢n)orward-ChainingåQ‰å’Œå½’纳法(Backward-ChainingåQ‰ã€‚æ¼”¾lŽæ³•从一个初始的事实出发åQŒä¸æ–­åœ°åº”用规则得出¾l“论åQˆæˆ–执行指定的动作)(j¨ª)。而归¾UÏx³•则是æ ÒŽ(gu¨©)®å‡è®¾åQŒä¸æ–­åœ°å¯ÀL‰¾½W¦åˆå‡è®¾çš„事实。Rete½Ž—法是目前效率最高的一个Forward-Chaining推理½Ž—法åQŒè®¸å¤šJava规则引擎都是åŸÞZºŽRete½Ž—法来进行推理计½Ž—的。推理引擎的推理步骤如下åQ?1)ž®†åˆå§‹æ•°æ®ï¼ˆfactåQ‰è¾“å…¥Working Memoryã€?2)使用Pattern Matcher比较规则库(rule baseåQ‰ä¸­çš„规则(ruleåQ‰å’Œæ•°æ®åQˆfactåQ‰ã€?3)如果执行规则存在冲突åQˆconflictåQ‰ï¼Œå›_Œæ—¶æ¿€‹zÖMº†(ji¨£n)多个规则åQŒå°†å†²çªçš„规则放入冲½Hé›†åˆã€?4)解决冲突åQŒå°†‹È€‹zȝš„规则按顺序放入Agendaã€?5)使用执行引擎执行Agenda中的规则。重复步éª?è‡?åQŒç›´åˆ°æ‰§è¡Œå®Œæ¯•所有Agenda中的规则。上˜q°å³æ˜¯è§„则引擎的原始架构åQŒJava规则引擎ž®±æ˜¯ä»Žè¿™ä¸€åŽŸå§‹æž¶æž„æ¼”å˜è€Œæ¥çš„ã€?strong>2、规则引擎相å…Ïxž„ä»?/strong>规则引擎是一¿Uæ ¹æ®è§„则中包含的指定过滤条ä»Óž¼Œåˆ¤æ–­å…¶èƒ½å¦åŒ¹é…è¿è¡Œæ—¶åˆÈš„实时条äšg来执行规则中所规定的动作的引擎。与规则引擎相关的有四个基本概念åQŒäØ“(f¨´)更好地理解规则引擎的工作原理åQŒä¸‹é¢å°†å¯¹è¿™äº›æ¦‚念进行逐一介绍ã€?)信息元(Information UnitåQ‰ä¿¡æ¯å…ƒæ˜¯è§„则引擎的基本建筑块,它是一个包含了(ji¨£n)特定事äšg的所有信息的对象。这些信息包括:(x¨¬)消息、äñ”生事件的应用½E‹åºæ ‡è¯†ã€äº‹ä»¶äñ”生事件、信息元¾cÕdž‹ã€ç›¸å…Œ™§„则集、通用æ–ÒŽ(gu¨©)³•、通用属性以å?qi¨¢ng)一些系¾lŸç›¸å…³ä¿¡æ¯ç­‰½{‰ã€?2)信息服务åQˆInformation ServicesåQ‰ä¿¡æ¯æœåŠ¡äñ”生信息元对象。每个信息服务äñ”生它自己¾cÕdž‹ç›¸å¯¹åº”的信息元对象。即特定信息服务æ ÒŽ(gu¨©)®ä¿¡æ¯å…ƒæ‰€äº§ç”Ÿæ¯ä¸ªä¿¡æ¯å…ƒå¯¹è±¡æœ‰ç›¸åŒçš„æ ¼å¼ï¼Œä½†å¯ä»¥æœ‰ä¸åŒçš„属性和规则集。需要注意的是,在一台机器上可以˜qè¡Œè®¸å¤šä¸åŒçš„信息服务,˜q˜å¯ä»¥è¿è¡ŒåŒä¸€ä¿¡æ¯æœåŠ¡çš„ä¸åŒå®žä¾‹ã€‚ä½†æ— è®ºå¦‚ä½•åQŒæ¯ä¸ªä¿¡æ¯æœåŠ¡åªäº§ç”Ÿå®ƒè‡ªå·Þq±»åž‹ç›¸å¯¹åº”的信息元ã€?)规则集(Rule SetåQ‰é¡¾åæ€ä¹‰åQŒè§„则集ž®±æ˜¯è®¸å¤šè§„则的集合。每条规则包含一个条件过滤器和多个动作。一个条件过滤器可以包含多个˜q‡æ×o(h¨´)条äšg。条件过滤器是多个布?y¨­u)®”(d¨¡ng)表辑ּçš„组合,其组合结果仍然是一个布?y¨­u)®”(d¨¡ng)类型的。在½E‹åº˜qè¡Œæ—Óž¼ŒåŠ¨ä½œž®†ä¼š(x¨¬)在条件过滤器å€égØ“(f¨´)真的情况下执行。除äº?ji¨£n)一般的执行动作åQŒè¿˜æœ‰ä¸‰¾cÀL¯”较特别的动作åQŒå®ƒä»¬åˆ†åˆ«æ˜¯åQšæ”¾å¼ƒåŠ¨ä½œï¼ˆDiscard ActionåQ‰ã€åŒ…含动作(Include ActionåQ‰å’Œä½¿ä¿¡æ¯å…ƒå¯¹è±¡å†…容持久化的动作。前两种动作¾cÕdž‹çš„区别将åœ?.3规则引擎工作机制ž®èŠ‚ä»‹ç»ã€?)队列½Ž¡ç†å™¨ï¼ˆQueue ManageråQ‰é˜Ÿåˆ—管理器用来½Ž¡ç†æ¥è‡ªä¸åŒä¿¡æ¯æœåŠ¡çš„ä¿¡æ¯å…ƒå¯¹è±¡çš„é˜Ÿåˆ—ã€‚ä¸‹é¢å°†ç ”ç©¶è§„åˆ™å¼•æ“Žçš„è¿™äº›ç›¸å…Ïxž„件是如何协同工作的。如å›?所½Cºï¼Œå¤„理˜q‡ç¨‹åˆ†äØ“(f¨´)四个阶段˜q›è¡ŒåQšä¿¡æ¯æœåŠ¡æŽ¥å—äº‹ä»¶åÆˆž®†å…¶è½¬åŒ–ä¸ÞZ¿¡æ¯å…ƒåQŒç„¶åŽè¿™äº›ä¿¡æ¯å…ƒè¢«ä¼ ¾l™é˜Ÿåˆ—管理器åQŒæœ€åŽè§„则引擎接收这些信息元òq¶åº”用它们自íw«æºå¸¦çš„规则加以执行åQŒç›´åˆ°é˜Ÿåˆ—管理器中不再有信息元ã€?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213335984478.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">å›? 处理˜q‡ç¨‹åä½œå›?strong>3、规则引擎的工作机制</strong>下面专门研究规则引擎的内部处理过½E‹ã€‚如å›?所½Cºï¼Œè§„则引擎从队列管理器中依‹Æ¡æŽ¥æ”¶ä¿¡æ¯å…ƒåQŒç„¶åŽä¾è§„则的定义顺序检查信息元所带规则集中的规则。如图所½Cºï¼Œè§„则引擎‹‚€(g¨¨)æŸ¥ç¬¬ä¸€ä¸ªè§„åˆ™åÆˆå¯¹å…¶æ¡äšg˜q‡æ×o(h¨´)器求å€û|¼Œå¦‚æžœå€égØ“(f¨´)假,所有与此规则相关的动作皆被忽略òq¶ç‘ô¾l­æ‰§è¡Œä¸‹ä¸€æ¡è§„则。如果第二条规则的过滤器å€égØ“(f¨´)真,所有与此规则相关的动作皆依定义™åºåºæ‰§è¡ŒåQŒæ‰§è¡Œå®Œæ¯•ç‘ô¾l­ä¸‹ä¸€æ¡è§„则。该信息元中的所有规则执行完毕后åQŒä¿¡æ¯å…ƒ?y¨­u)®†è¢«é”€æ¯ï¼Œç„¶åŽä»Žé˜Ÿåˆ—管理器接收下一个信息元。在˜q™ä¸ª˜q‡ç¨‹ä¸­åƈ未考虑两个ç‰ÒŽ(gu¨©)®ŠåŠ¨ä½œåQšæ”¾å¼ƒåŠ¨ä½œï¼ˆDiscard ActionåQ‰å’ŒåŒ…含动作åQˆInclude ActionåQ‰ã€‚放弃动作如果被执行åQŒå°†ä¼?x¨¬)蟩˜q‡å…¶æ‰€åœ¨ä¿¡æ¯å…ƒä¸­æŽ¥ä¸‹æ¥çš„æ‰€æœ‰è§„则,òq‰™”€æ¯æ‰€åœ¨ä¿¡æ¯å…ƒåQŒè§„则引擎ç‘ô¾l­æŽ¥æ”‰™˜Ÿåˆ—管理器中的下一个信息元。包含动作其实就是动作中包含其它现存规则集的动作。包含动作如果被执行åQŒè§„则引擎将暂停òq¶è¿›å…¥è¢«åŒ…含的规则集åQŒæ‰§è¡Œå®Œæ¯•后åQŒè§„则引擎还ä¼?x¨¬)返回原来暂停的地方¾l§ç®‹æ‰§è¡Œã€‚这一˜q‡ç¨‹ž®†é€’å½’˜q›è¡Œã€?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213340025059.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">å›? 规则引擎工作机制Java规则引擎的工作机制与上述规则引擎机制十分¾cÖM¼¼åQŒåªä¸è¿‡å¯¹ä¸Š˜q°æ¦‚念进行了(ji¨£n)重新包装¾l„合。Java规则引擎å¯ÒŽ(gu¨©)äº¤ç»™å¼•擎的Java数据对象˜q›è¡Œ‹‚€(g¨¨)索,æ ÒŽ(gu¨©)®˜q™äº›å¯¹è±¡çš„当前属性值和它们之间的关¾p»ï¼Œä»ŽåŠ è½½åˆ°å¼•æ“Žçš„è§„åˆ™é›†ä¸­å‘çŽ°ç¬¦åˆæ¡ä»¶çš„è§„åˆ™åQŒåˆ›å»ø™¿™äº›è§„则的执行实例。这些实例将在引擎接到执行指令时、依照某¿Uä¼˜å…ˆåºä¾æ¬¡æ‰§è¡Œã€‚一般来è®ÔŒ¼ŒJava规则引擎内部ç”׃¸‹é¢å‡ ä¸ªéƒ¨åˆ†æž„成:(x¨¬)工作内存åQˆWorking MemoryåQ‰å³å·¥ä½œåŒºï¼Œç”¨äºŽå­˜æ”¾è¢«å¼•擎引用的数据对象集合åQ›è§„则执行队列,用于存放被激‹zȝš„规则执行实例;é?r¨´n)态规则区åQŒç”¨äºŽå­˜æ”¾æ‰€æœ‰è¢«åŠ è²çš„ä¸šåŠ¡è§„åˆ™ï¼Œ˜q™äº›è§„则ž®†æŒ‰ç…§æŸ¿Uæ•°æ®ç»“构组¾l‡ï¼Œå½“工作区中的数据发生改变后,引擎需要迅速根据工作区中的对象现状åQŒè°ƒæ•´è§„则执行队列中的规则执行实例。Java规则引擎的结构示意图如图4所½Cºã€?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213340010350.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">å›? Java规则引擎工作机制当引擎执行时åQŒä¼š(x¨¬)æ ÒŽ(gu¨©)®è§„则执行队列中的优先™åºåºé€æ¡æ‰§è¡Œè§„则执行实例åQŒç”±äºŽè§„则的执行部分可能ä¼?x¨¬)改变工作区的数据对象,从而会(x¨¬)佉K˜Ÿåˆ—中的某些规则执行实例因为条件改变而失效,必须从队列中撤销åQŒä¹Ÿå¯èƒ½ä¼?x¨¬)æ¿€‹zÕdŽŸæ¥ä¸æ»¡èƒö条äšg的规则,生成新的规则执行实例˜q›å…¥é˜Ÿåˆ—。于是就产生äº?ji¨£n)一¿Uâ€œåŠ¨æ€â€çš„è§„åˆ™æ‰§è¡Œé“¾ï¼Œå½¢æˆè§„åˆ™çš„æŽ¨ç†æœºåˆ¶ã€‚è¿™¿Uè§„则的“链式”反应完全是由工作区中的数据驱动的ã€?ä»ÖM½•一个规则引擎都需要很好地解决规则的推理机制和规则条äšg匚w…çš„æ•ˆçŽ‡é—®é¢˜ã€‚è§„åˆ™æ¡ä»¶åŒ¹é…çš„æ•ˆçŽ‡å†›_®šäº?ji¨£n)引擎的性能åQŒå¼•擎需要迅速测试工作区中的数据对象åQŒä»ŽåŠ è²çš„è§„åˆ™é›†ä¸­å‘çŽ°ç¬¦åˆæ¡ä»¶çš„è§„åˆ™åQŒç”Ÿæˆè§„则执行实例ã€?982òq´ç¾Žå›½å¡è€åŸºÂ·æ¢…隆大学的Charles L. Forgy发明äº?ji¨£n)一¿Uå«Rete½Ž—法åQŒå¾ˆå¥½åœ°è§£å†³äº?ji¨£n)这斚w¢çš„问题。目前世界顶ž®–的商用业务规则引擎产品基本上都使用Rete½Ž—法ã€?/p><img src ="http://www.aygfsteel.com/clant/aggbug/87951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/clant/" target="_blank">BPM </a> 2006-12-15 15:19 <a href="http://www.aygfsteel.com/clant/articles/87951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>åQˆå…­åQ? Drools规则语言详解åQˆä¸ŠåQ?http://www.aygfsteel.com/clant/articles/85146.htmlBPM BPM Sun, 03 Dec 2006 01:56:00 GMThttp://www.aygfsteel.com/clant/articles/85146.htmlhttp://www.aygfsteel.com/clant/comments/85146.htmlhttp://www.aygfsteel.com/clant/articles/85146.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85146.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85146.html Drools 规则语言详解åQˆä¸ŠåQ?br />

<!--[if !supportLists]--> 1åQ?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> 概述åQ?/span>

Drools 3 采用äº?ji¨£n)原生的规则语言åQŒé‚£æ˜¯ä¸€¿Uéž XML 文本格式。在½W¦å·æ–šw¢åQŒè¿™¿Uæ ¼å¼æ˜¯éžå¸¸è½»é‡çš„,òq¶ä¸”通过â€?/span> expanders ”支持符合你问题域的 Domain Specific Language åQ?/span> DSL åQ‰ã€‚这一章把焦点攑֜¨äº?/span> Drools 原生的规则格式。如果你想从技术上äº?ji¨£n)解规则语言的机åˆÓž¼Œå¯ä»¥å‚考â€?/span> drl.g ”源文äšgåQŒè¿™æ˜¯ç”¨ Antlr3 语法来描˜q°è§„则语­a€ã€‚如果你使用 Rule Workbench åQŒå†…容助手将ä¼?x¨¬)äØ?f¨´)你完成大量的规则¾l“æž„åQŒä¾‹å¦‚输入â€?/span> ru ”,然后æŒ?/span> ctrl åQ?/span> space åQŒä¼š(x¨¬)ä¸ÞZ½ å»ºç«‹è§„则¾l“æž„ã€?br />

<!--[if !supportLists]--> 1.1    <!--[endif]--> 规则文äšg

一个规则文仉™€šå¸¸æ˜¯ä¸€ä¸ªä»¥ .drl 扩展名结ž®„¡š„æ–‡äšg。在一ä¸?/span> drl æ–‡äšg中,你可以有多条 rules åQ?/span> functions ½{‰ç­‰ã€‚å°½½Ž¡å¦‚此,你也可以ž®†ä½ çš„规则分布在多个文äšg中,˜q™æœ‰åˆ©äºŽ½Ž¡ç†å¤§é‡çš„规则。一ä¸?/span> DRL æ–‡äšg是一个简单的文本文äšgã€?/span>

1.2 规则的结�/span>

一个规则结构大致如下:(x¨¬)

rule  " name "
    ATTRIBUTES
    when
        LHS
    then
        RHS
end

可以看到åQŒè¿™æ˜¯éžå¸¸ç®€å•的。通常的标点符号都是不需要的åQŒç”šè‡Œ™¿žâ€?/span> name ”的双引号都是不需要的ã€?/span> ATTRIBUTES 是简单的åQŒä¹Ÿæ˜¯å¯é€‰çš„åQŒæ¥æç¤ºè§„则的行为方式ã€?/span> LHS 是规则的条äšg部分åQŒéœ€è¦æŒ‰ç…§ä¸€å®šçš„语法来写ã€?/span> RHS 基本上是一个允许执è¡?/span> Java 语法的代码的块(以后ž®†ä¼š(x¨¬)支持 groovy å’?/span> C åQƒï¼‰(j¨ª)。ä“Q何在 LHS 中ä‹É用的变量都可以在 RHS 中ä‹É用ã€?/span>

注意åQšæ¯è¡Œå¼€å§‹çš„½Iºæ ¼æ˜¯ä¸é‡è¦çš„,除非åœ?/span> DSL åQ?/span> Domain Specific Language åQ‰è¯­­a€ä¸­æœ‰ç‰¹åˆ«çš„æŒ‡æ˜Žã€?/span>

<!--[if !supportLists]--> 1.3   <!--[endif]--> Domain Specific Language

Domain Specific Language 是对原生规则语言的加强。它们ä‹É用â€?/span> expander ”机制ã€?/span> Expander 机制是一¿Uå¯æ‰©å±•çš?/span> API 。你可以使用 .dsl æ–‡äšgåQŒæ¥æä¾›ä»ŽåŸŸæˆ–自然语­a€åˆ°è§„则语­a€å’Œä½ çš„域对象的映ž®„。你可以ž®?/span> .dsl æ–‡äšg看成是对你的域模型的映射ã€?/span> DSL 提供äº?ji¨£n)更高的规则可读性,你可以选择使用你自己创建的 DSL åQŒæˆ–者是原生的规则语­a€ã€?/span>

1.4 保留�/span>

在规则语­a€ä¸­å­˜åœ¨ä¸€äº›ä¿ç•™å­—。你应该避免使用˜q™äº›ä¿ç•™å­—,来命名规则文本中的域对象åQŒå±žæ€§ï¼Œæ–ÒŽ(gu¨©)³•åQŒåŠŸèƒ½ã€‚ä¿ç•™å­—å¦‚ä¸‹åQ?/span> when åQ?/span> then åQ?/span> rule åQ?/span> end åQ?/span> contains åQ?/span> matches åQ?/span> and åQ?/span> or åQ?/span> modify åQ?/span> retract åQ?/span> assert åQ?/span> salience åQ?/span> function åQ?/span> query åQ?/span> exists åQ?/span> eval åQ?/span> agenda-group åQ?/span> no-loop åQ?/span> duration åQ?/span> -> åQ?/span> not åQ?/span> auto-focus ã€?/span>

<!--[if !supportLists]--> 2.   <!--[endif]--> 注释

2.1 单行注释åQ?/span>

Figure 2.1. Single line comment

2.2 多行注释åQ?br />

Figure 2.2. Multi line comment

<!--[if !supportLists]-->

3.     <!--[endif]--> Package

一个包æ˜?/span> rule 和其他相关结构,åƒ?/span> import å’?/span> global 的集合ã€?/span> Package 的成员之间通常都是相关联的。一ä¸?/span> Package 代表äº?ji¨£n)一个命名空é—ß_(d¨¢)¼ˆ namespace åQ‰ï¼Œç”¨æ¥ä½¿ç»™å®šçš„规则¾l„之间保持唯一性ã€?/span> Package 的名字本íw«å°±æ˜¯å‘½åç©ºé—ß_(d¨¢)¼Œòq¶ä¸”与文件或文äšgå¤¹åÆˆæ— å…³è”ã€?/span>

<!--[if !supportEmptyParas]-->

可以ž®†æ¥è‡ªä¸åŒè§„åˆ™æºçš„è§„åˆ™è£…é…åœ¨ä¸€èµøP¼Œå‰ææ˜¯è¿™äº›è§„则必™åÕd¤„在同一个命名空间中。尽½Ž¡å¦‚此,一个通常的结构是ž®†å¤„于同一个命名空间中的所有规则都攑֜¨åŒä¸€ä¸ªç›¸åŒçš„æ–‡äšg中ã€?/span>

下面çš?/span> rail-road 图显½CÞZº†(ji¨£n)¾l„成一ä¸?/span> Package 的所有组件。注意:(x¨¬)一ä¸?/span> package 必须有一个命名空é—ß_(d¨¢)¼Œòq¶ä¸”采用 Java 包名的约定。在一个规则文件中åQŒå„¾l„äšg出现的位¾|®æ˜¯ä»ÀL„çš„,除了(ji¨£n)â€?/span> package ”和â€?/span> expander ”语句必™åÕd‡ºçŽ°åœ¨ä»ÖM½•一个规则之前,攑֜¨æ–‡äšg的顶部。在ä»ÖM½•情况下,分号都是可选的ã€?/span>


Figure 3.1. package
3.1 import

Figure 3.2. import

Import 语句的ä‹É用很åƒ?/span> Java 中的 import è¯­å¥ã€‚ä½ éœ€è¦äØ“(f¨´)你要在规则中使用的对象,指定完整的èµ\径和¾cÕdã€?/span> Drools 自动从相同命名的 java 包中引入所需的类ã€?/span>

3.2 expander

Figure 3.3. expander

expander 语句是可选的åQŒæ˜¯ç”¨æ¥æŒ‡å®š Domain Specific Language 的配¾|®ï¼ˆé€šå¸¸æ˜¯ä¸€ä¸?/span> .dsl æ–‡äšgåQ‰ã€‚这使得解析器可以理解用你自å·Þqš„ DSL 语言所写的规则ã€?/span>

3.3 global


Figure 3.4. global

Global ž®±æ˜¯å…¨å±€å˜é‡ã€‚如果多ä¸?/span> package 声明äº?ji¨£n)具有相同标识符ç?/span> global åQŒé‚£ä¹ˆå®ƒä»¬å¿…需是相同的¾cÕdž‹åQŒåƈ且所有的引用都是相同的。它们通常用来˜q”回数据åQŒæ¯”å¦?/span> actions çš„æ—¥å¿—ï¼Œæˆ–è€…äØ“(f¨´) rules 提供所需的数据或服务ã€?/span> global òq¶ä¸æ˜¯é€šè¿‡ assert 动作攑օ¥ WorkingMemory 的,所有当 global 发生改变æ—Óž¼Œå¼•擎ž®†ä¸ä¼?x¨¬)知道。所以, global ä¸èƒ½ä½œäØ“(f¨´)¾U¦æŸæ¡äšgåQŒé™¤éžå®ƒä»¬çš„值是 final 的。将 global 错误的ä‹É用在¾U¦æŸæ¡äšg中,ä¼?x¨¬)äñ”生ä×o(h¨´)人惊讶的错误¾l“æžœã€?/span>

<!--[if !supportEmptyParas]-->

注意åQ?/span> global 只是从你çš?/span> application 中传å…?/span> WorkingMemory 的对象的命名实例。这意味着你可以传入ä“Q何你惌™¦çš„对象。你可以传入一ä¸?/span> service locator åQŒæˆ–者是一ä¸?/span> service 本èínã€?/span>

<!--[if !supportEmptyParas]-->

下面的例子中åQŒæœ‰ä¸€ä¸?/span> EmailService 的实例。在你调用规则引擎的代码中,你有一ä¸?/span> EmailService 对象åQŒç„¶åŽæŠŠå®ƒæ”¾å…?/span> WorkingMemory 。在 DRL æ–‡äšg中,你声明了(ji¨£n)ä¸€ä¸ªç±»åž‹äØ“(f¨´) EmailService çš?/span> global åQŒç„¶åŽå°†å®ƒå‘½åäØ“(f¨´)â€?/span> email â€ï¼Œåƒè¿™æ øP¼š(x¨¬) global EmailService email åQ›ã€‚然后在你的规则çš?/span> RHS 中,你可以ä‹É用它åQŒåƒ˜q™æ ·åQ?/span> email.sendSMS(number,message) ½{‰ç­‰ã€?/span>

4. Function


Figure 4.1. function

Function 是将代码攑ֈ°ä½ çš„规则源中的一¿Uæ–¹æ³•。它们只能做¾cÖM¼¼ Helper ¾cÕdšçš„事åQˆå®žé™…上¾~–译器在背后帮你生成äº?/span> Helper ¾c»ï¼‰(j¨ª)。在一ä¸?/span> rule 中ä‹Éç”?/span> function 的主要优势是åQŒä½ å¯ä»¥ä¿æŒæ‰€æœ‰çš„逻辑都在一个地方,òq¶ä¸”你可以根据需要来改变 function åQˆè¿™å¯èƒ½æ˜¯å¥½äº‹ä¹Ÿå¯èƒ½æ˜¯åäº‹ï¼‰(j¨ª)ã€?/span> Function 最有用的就是在规则çš?/span> RHS 调用 actions åQŒç‰¹åˆ«æ˜¯å½“é‚£ä¸?/span> action 需要反复调用的时候ã€?/span>

<!--[if !supportEmptyParas]-->

一个典型的 function 声明如下åQ?/span>

function String calcSomething(String arg) {
return   " hola ! " ;
}

<!--[if !supportEmptyParas]-->

注意åQšâ€?/span> function ”关键字的ä‹Éç”¨ï¼Œå®ƒåÆˆä¸çœŸæ­£æ˜¯ Java 的一部分。è€?/span> function 的参数就像是一个普通的 method åQˆå¦‚果不需要参数就不用写)(j¨ª)。返回类型也跟普通的 method 一栗÷€‚在一条规则(在它çš?/span> RHS 中,或可能是一ä¸?/span> eval åQ‰ä¸­è°ƒç”¨ function åQŒå°±åƒè°ƒç”¨ä¸€ä¸?/span> method ä¸€æ øP¼Œåªéœ€è¦?/span> function 的名字,òq¶ä¼ ¾l™å®ƒå‚æ•°ã€?/span>

<!--[if !supportEmptyParas]-->

function 的替代品åQŒå¯ä»¥ä‹É用一ä¸?/span> Helper ¾cÖM¸­çš„静(r¨´n)态方法:(x¨¬) Foo.doSomething() åQŒæˆ–者以 global 的方式传入一ä¸?/span> Helper ¾cÀLˆ–服务的实例:(x¨¬) foo.doSomething() åQ?/span> foo 是一个命名的 global 变量åQ‰ã€?/span>

<!--[if !supportEmptyParas]-->



]]>
åQˆä¸ƒåQ? Drools规则语言详解åQˆä¸‹åQ?http://www.aygfsteel.com/clant/articles/85147.htmlBPM BPM Sun, 03 Dec 2006 01:56:00 GMThttp://www.aygfsteel.com/clant/articles/85147.htmlhttp://www.aygfsteel.com/clant/comments/85147.htmlhttp://www.aygfsteel.com/clant/articles/85147.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85147.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85147.html阅读全文

]]>
åQˆäº”åQ? JBoss Rules 3.0.1 ¾cÕdº“介绍 http://www.aygfsteel.com/clant/articles/85145.htmlBPM BPM Sun, 03 Dec 2006 01:55:00 GMThttp://www.aygfsteel.com/clant/articles/85145.htmlhttp://www.aygfsteel.com/clant/comments/85145.htmlhttp://www.aygfsteel.com/clant/articles/85145.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85145.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85145.html 下蝲地址åQ?/span>

http://labs.jboss.com/portal/index.html?ctrl:id=page.default.downloads&project=jbossrules

下蝲文äšg说明åQ?/span>

JBoss Rules 3.0.1 Binaries (includes javadocs) åQ?/span> 13MB åQ‰â€?/span> 仅仅包含 JBoss Rules 的四个核å¿?j¨©)类库ï¼?x¨¬)

<!--[if !supportLists]--> l         <!--[endif]--> drools-core.jaråQ?/span>核心(j¨©)引擎åQŒè¿è¡Œæ—¶¾l„äšg。包含了(ji¨£n)RETE引擎å’?/span>LEAPS引擎åQ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-compiler.jaråQ?/span>规则文äšg的编译组ä»Óž¼Œæž„徏可执行的RuleBaseåQ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-jsr94.jaråQ?/span>提供äº?/span>JSR-94的兼容实玎ͼŒæœ¬è´¨ä¸Šæ˜¯drools- compiler¾l„äšg的包裹层。注意:(x¨¬)ç”׃ºŽJSR94规约的限åˆÓž¼Œä¸æ˜¯æ‰€æœ‰çš„特点都可以通过此接口暴霌Ӏ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-decisiontables.jaråQ?/span>决策表的“编译”组ä»Óž¼ˆä½¿ç”¨äº?/span>drools- compiler¾l„äšgåQ‰ã€‚支æŒ?/span>excelå’?/span>CSV输入格式ã€?/span>

JBoss Rules 3.0.1 Binaries with dependencies (includes javadocs) åQ?/span> 23 MB åQ‰ï¼ 包含äº?/span> JBoss Rules 的核å¿?j¨©)类库和它们ç?/span> dependencies åQ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> antlr-2.7.6.jar

<!--[if !supportLists]--> l         <!--[endif]--> antlr-3.0ea8.jar

<!--[if !supportLists]--> l         <!--[endif]--> colt-1.2.0.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-collections-3.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-io-1.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-core-1.0-406301.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-eclipse-3.2.0.666.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-janino-2.4.3.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-lang-2.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-logging-api-1.0.4.jar

<!--[if !supportLists]--> l         <!--[endif]--> concurrent-1.3.4.jar

<!--[if !supportLists]--> l         <!--[endif]--> core-3.2.0.666.jar

<!--[if !supportLists]--> l         <!--[endif]--> janino-2.4.3.jar

<!--[if !supportLists]--> l         <!--[endif]--> jsr94-1.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> jung-1.7.2.jar

<!--[if !supportLists]--> l         <!--[endif]--> junit-3.8.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> poi-2.5.1-final-20040804.jar

<!--[if !supportLists]--> l         <!--[endif]--> stringtemplate-2.3b6.jar

<!--[if !supportLists]--> l         <!--[endif]--> xercesImpl-2.6.2.jar

<!--[if !supportLists]--> l         <!--[endif]--> xml-apis-1.0.b2.jar

<!--[if !supportLists]--> l         <!--[endif]--> xpp3-1.1.3.4.0.jar

<!--[if !supportLists]--> l         <!--[endif]--> xstream-1.1.3.jar

如果你运行在 Java 1.5 环境下,有一些类库,例如 XML libraries åQŒå¯ä»¥ä¸éœ€è¦ã€‚需要注意的¾cÕdº“有:(x¨¬)

â€?/span> JCI ”-˜q™æ˜¯ Apache Java Compiler Interface , 提供äº?ji¨£n)运行时¾~–译能力。可以通过 PackageBuilderConfiguration 实例来设定采ç”?/span> eclipse æˆ?/span> janino ¾~–译器,默认æ˜?/span> eclipse åQ?/span>

â€?/span> POI ”-提供äº?ji¨£n)è§£æ?/span> Excel æ–‡äšg的能力;

â€?/span> antlr ”-提供äº?ji¨£n)解析规则语­a€çš„能力ã€?/span>

JBoss Rules IDE 3.0.1 åQ?/span> 13 MB åQ‰ï¼ ˜q™æ˜¯ JBoss Rules çš?/span> Eclipse 插äšgåQŒåªæ”¯æŒ Eclipse 3.2 或以上版本。它提供äº?ji¨£n)运è?/span> JBoss Rules 的所æœ?/span> dependencies 。你可以创徏一ä¸?/span> Rule Project åQŒå®ƒèƒ½å¤Ÿä¸ÞZ½ ¾~–写规则文äšg提供自动完成的功能,òq¶ä¸”å®ƒäØ“(f¨´)你提供了(ji¨£n) Agenda view åQ?/span> WorkingMemory view åQ?/span> Global Data view åQŒä‹É你可以通过 eclipse 视图很清楚的看到 Agenda åQ?/span> WorkingMemory å’?/span> Global Data 的情å†üc(di¨£n)€?/span>

你还可以通过 update site 来自动安装这个插ä»?/span> ,URL 是:(x¨¬)

http://anonsvn.labs.jboss.com/labs/jbossrules/updates/drools-ide-update/

<!--[if !supportEmptyParas]--> <!--[endif]-->



]]>
åQˆä¸‰åQ? Drools规则引擎 åQˆä¸ŠåQ?http://www.aygfsteel.com/clant/articles/85143.htmlBPM BPM Sun, 03 Dec 2006 01:54:00 GMThttp://www.aygfsteel.com/clant/articles/85143.htmlhttp://www.aygfsteel.com/clant/comments/85143.htmlhttp://www.aygfsteel.com/clant/articles/85143.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85143.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85143.html从今天开始,我们ž®†åˆ†ä¸¤æœŸæ¥è¯¦¾l†çš„介绍Drools规则引擎的原理,和各关键¾cȝš„使用æ–ÒŽ(gu¨©)³•ã€?br />
Drools 规则引擎(�

1. 概述 :
Drools åˆ†äØ“(f¨´)两个主要部分åQšæž„å»ºï¼ˆ Authoring åQ‰å’Œ˜qè¡Œæ—Óž¼ˆ Runtime åQ‰ã€?br />
构徏的过½E‹æ¶‰å?qi¨¢ng)åˆ?/span> .drl æˆ?/span> .xml 规则文äšg的创建,它们被读入一个解析器åQŒä‹Éç”?/span> ANTLR 3 语法˜q›è¡Œè§£æžã€‚解析器对语法进行正¼‹®æ€§çš„‹‚€(g¨¨)查,然后产生一¿Uä¸­é—´ç»“æž„â€?/span> descr ”, descr ç”?/span> AST 来描˜q°è§„则ã€?/span> AST 然后被传åˆ?/span> PackageBuilder åQŒç”± PackagBuilder 来äñ”ç”?/span> Packaged 对象ã€?/span> PackageBuilder ˜q˜æ‰¿æ‹…着一些代码äñ”生和¾~–译的工作,˜q™äº›å¯¹äºŽäº§ç”Ÿ Package 对象都时必需的ã€?/span> Package
对象是一个可以配¾|®çš„åQŒå¯åºåˆ—化的åQŒç”±ä¸€ä¸ªæˆ–多个规则¾l„成的对象。下å›ùN˜æ˜Žäº†(ji¨£n)上述˜q‡ç¨‹åQ?/font>
 
Figure 1.1
Authoring Components

RuleBase 是一个运行时¾l„äšgåQŒå®ƒåŒ…含äº?ji¨£n)一个或多个 Package 对象。可以在ä»ÖM½•时刻ž®†ä¸€ä¸?/span> Package 对象加入或移å‡?/span> RuleBase 对象。一ä¸?/span> RuleBase 对象可以在ä“Q意时åˆÕd®žä¾‹åŒ–一个或多个 WorkingMemory 对象åQŒåœ¨å®ƒçš„内部保持对这äº?/span> WorkingMemory 的弱引用ã€?/span> WorkingMemory ç”׃¸€¾pÕdˆ—子组件组成。当应用½E‹åºä¸­çš„对象è¢?/span> assert ˜q?/span> WorkingMemory åQŒå¯èƒ½ä¼š(x¨¬)坯D‡´ä¸€ä¸ªæˆ–多个 Activation çš„äñ”生,然后ç”?/span> Agenda 负责安排˜q™äº› Activation 的执行。下图说明了(ji¨£n)上述˜q‡ç¨‹åQ?/span>

 
Figure 1.2 . Runtime Components

2åQŽæž„建(AuthoringåQ‰ï¼š(x¨¬)

主要有三个类用来完成构徏˜q‡ç¨‹åQ?/span>DrlParser, XmlParser å’?/span> PackageBuilder。两个解析器¾cÖM»Žä¼ å…¥çš?/span>Reader实例产生descr AST模型ã€?/span>PackageBuilder提供äº?ji¨£n)简便的APIåQŒä‹É你可以忽略那两个¾cȝš„存在。这两个½Ž€å•çš„æ–ÒŽ(gu¨©)³•是:(x¨¬)â€?/span>addPackageFromDrl”和â€?/span>addPackageFromXml”,两个都只要传入一ä¸?/span>Readerå®žä¾‹ä½œäØ“(f¨´)参数。下面的例子说明äº?ji¨£n)如何ä»?/span>classpath中的xmlå’?/span>drlæ–‡äšg创徏一ä¸?/span>Package对象。注意:(x¨¬)所有传入同一ä¸?/span>PackageBuilder实例的规则源åQŒéƒ½å¿…须是在相同çš?/span>package 命名½Iºé—´åQ?/span>namespaceåQ‰ä¸­ã€?/span>

PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( 
new I(y¨ªng)nputStreamReader( getClass().getResourceAsStream( "package1.drl" ) ) );
builder.addPackageFromXml( 
new I(y¨ªng)nputStreamReader( getClass().getResourceAsStream( "package2.drl" ) ) );
Package pkg 
= builder.getPackage();


Figure 2.1 PackageBuilder

PackageBuilder是可以配¾|®çš„åQŒä‹Éç”?/span>PackageBuilderConfiguration。通常åQŒä½ å¯ä»¥æŒ‡å®šå¦ä¸€ä¸?/span>parent ClassLoader和用什么编译器åQ?/span>compileråQ‰ï¼Œé»˜è®¤æ˜?/span>Eclipse JDT。下面显½CÞZº†(ji¨£n)如何指定JANINO¾~–译器:(x¨¬)

PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
conf.setCompiler( PackageBuilderConfiguration.JANINO );
PackageBuilder builder 
= new PackageBuilder( conf );

Figure 2.2 . PackageBuilderConfiguration

3
åQ?/span>RuleBase:

Figure 3.1 . RuleBase

一ä¸?/span>RuleBase包含äº?ji¨£n)多个将被ä‹É用的规则包ï¼?/span>packages of rulesåQ‰ã€‚一ä¸?/span>RuleBase是可以序列化的,所以它可以被配¾|®åˆ°JNDI或其他类似的服务。通常åQŒç¬¬ä¸€‹Æ¡ä‹É用时åQŒä¸€ä¸?/span>RuleBaseè¢«åˆ›å»ºåÆˆ¾~“å­˜ã€?/span>RuleBaseç”?/span>RuleBaseFactory来实例化åQŒé»˜è®¤è¿”回一ä¸?/span>ReteOO RuleBase。可以传入参数来指定采用ReteOOæˆ?/span>Leaps。然后,ç”?/span>addPackageæ–ÒŽ(gu¨©)³•加入Package实例。你可以加入有相同命名空é—ß_(d¨¢)¼ˆnamespaceåQ‰çš„多个Packageã€?/span>

RuleBase ruleBase  = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);

Figure 3.2. RuleBaseFactory

一ä¸?/span> rulebase instance 是线½E‹å®‰å…¨çš„åQŒæ‰€æœ‰ä½ å¯ä»¥åœ¨ä½ çš„应用中åQŒè®©ä¸€ä¸?/span> rulebase instance 在多个线½E‹ä¸­å…׃ín。对于一ä¸?/span> rulebase 的最通常的操作是产生一个新çš?/span> WorkingMemory ã€?/span>

˜q™ä¸ª rulebase 保持着到它所产生çš?/span> WorkingMemoryd 的弱引用åQŒæ‰€ä»¥åœ¨é•¿æ—¶é—´è¿è¡Œçš„ WorkingMemory 中,如果 rules 发生改变åQŒè¿™äº?/span> WorkingMemory 可以即ä‹É的根据最新的 rules ˜q›è¡Œæ›´æ–°åQŒè€Œä¸å¿…重å?/span> WorkingMemory 。你也可以指å®?/span> RuleBase 不必保持一个弱引用åQŒä½†æ˜¯ä½ è¦ä¿è¯?/span> RuleBase 不用更新ã€?/span>

ruleBase.newWorkingMemory();   //  maintains a weak reference.
ruleBase.newWorkingMemory(  false  );  //  do not maintain a weak reference

ä»ÖM½•时候, Package 可以被加入或¿U»é™¤åQ›æ‰€æœ‰çš„æ”¹å˜éƒ½ä¼š(x¨¬)被反映到现存çš?/span> WorkingMemory 中。不要忘äº?ji¨£n)è°ƒç?/span> fireAllRules() è®?/span> Activations ‹È€å‘ã€?/span>

ruleBase.addPackage( pkg  );   //  Add a package instance
ruleBase.removePackage(  " org.com.sample "   );   //  remove a package, and all its parts, by it's namespace
ruleBase.removeRule(  " org.com.sample " ,  " my rule "  );  //  remove a specific rule from a namespace

虽然有删除一个单独规则的æ–ÒŽ(gu¨©)³•åQŒä½†æ˜¯å´æ²¡æœ‰åŠ å…¥ä¸€ä¸ªå•ç‹¬è§„åˆ™çš„æ–ÒŽ(gu¨©)³•åQˆè¦è¾‘Öˆ°˜q™ä¸ªç›®çš„只有加入一个只有一条规则的 package åQ‰ã€?/span>

<!--[if !supportEmptyParas]-->

RuleBaseConfigurator 可以指定 RuleBase 的附加行为。在加入 RuleBase 后, RuleBaseConfiguration ž®±å˜æˆä¸å¯å˜å¯¹è±¡ã€?/span>

RuleBaseConfiguration conf  =   new  RuleBaseConfiguration();

conf.setProperty( RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
                  RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY );

RuleBase ruleBase 
=   new  ReteooRuleBase( conf );

两个主要的属性是åQ?/span> PROPERT_ASSERT_BEHAVIOR å’?/span> PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR åQˆåœ¨ä»¥åŽçš„部分中ä¼?x¨¬)解释ï¼?j¨ª)。所有的属性值都æ˜?/span> RuleBaseConfiguration ¾cÖM¸­çš„静(r¨´n)态域帔R‡ã€?/span>


Figure 3.3 RuleBaseConfiguration



]]>
åQˆå››åQ? Drools规则引擎 åQˆä¸‹åQ?http://www.aygfsteel.com/clant/articles/85144.htmlBPM BPM Sun, 03 Dec 2006 01:54:00 GMThttp://www.aygfsteel.com/clant/articles/85144.htmlhttp://www.aygfsteel.com/clant/comments/85144.htmlhttp://www.aygfsteel.com/clant/articles/85144.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85144.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85144.html Drools 规则引擎(ä¸?

4 åQ?/span> WorkingMemory:

Figure 4.1 WorkingMemory

WorkingMemory 是运行时规则引擎的主要类。它保持äº?ji¨£n)所有被 asserted ˜q?/span> WorkingMemory 的数据的引用åQŒç›´åˆ°å–消( retracted åQ‰ã€?/span> WorkingMemory 是有状态对象。它们的生命周期可长可短。如果从一个短生命周期的角度来同一个引擎进行交互,意味着你可以ä‹Éç”?/span> RuleBase å¯¹è±¡æ¥äØ“(f¨´)每个 session 产生一个新çš?/span> WorkingMemory åQŒç„¶åŽåœ¨¾l“束 session å?/span> discard ˜q™ä¸ª WorkingMemory åQˆäñ”生一ä¸?/span> WorkingMemory 是一个廉ä»ïL(f¨¥ng)š„æ“ä½œåQ‰ã€‚另一¿UåŞ式,ž®±æ˜¯åœ¨ä¸€ä¸ªç›¸å½“长的时间中åQˆä¾‹å¦‚一ä¸?/span> conversation åQ‰ï¼Œä¿æŒä¸€ä¸?/span> WorkingMemory åQŒåƈ且对于新çš?/span> facts 保持持箋的更新。当你希æœ?/span> dispose 一ä¸?/span> WorkingMemory 的时候,最好的实践ž®±æ˜¯è°ƒç”¨ dispose() æ–ÒŽ(gu¨©)³•åQŒæ­¤æ—?/span> RuleBase 中对它的引用ž®†ä¼š(x¨¬)被移除(ž®½ç®¡˜q™æ˜¯ä¸€ä¸ªå¼±å¼•用åQ‰ã€‚不½Ž¡æ€Žæ ·æœ€åŽå®ƒ?y¨­u)®†ä¼?x¨¬)被当成垃圾收集掉。术è¯?/span> WorkingMemory Actions 代表äº?ji¨£n)å¯?/span> WorkingMemory çš?/span> assertions åQ?/span> retractions å’?/span> modifications ã€?/span>

4.1 Facts

Facts 是从你的应用中,è¢?/span> assert ˜q?/span> WorkingMemory 中的对象åQ?/span> beans åQ‰ã€?/span> Facts 是规则可以访问的ä»ÀL„çš?/span> java 对象。规则引擎中çš?/span> facts òq¶ä¸æ˜¯â€?/span> clone â€?/span> facts åQŒå®ƒåªæ˜¯æŒæœ‰åˆîC½ çš„应用中数据的引用ã€?/span> Facts 是你的应用数据ã€?/span> String 和其他没æœ?/span> getter å’?/span> setter 的类不是有效çš?/span> Fact 。这æ ïL(f¨¥ng)š„¾cÖM¸èƒ½ä‹É用域¾U¦æŸåQ?/span> Field Constraints åQ‰ï¼Œå› äØ“(f¨´)使用域约束要依靠 JavaBean 标准çš?/span> getter å’?/span> setter 来同对象交互ã€?/span>

4.2 Assertion

“Assertionâ€?/span> 是将 facts 告诉 WorkingMemory 的动作,例如 WorkingMemory.assertObject (yourObject) 。当ä½?/span> assert 一ä¸?/span> fact åQŒå®ƒ?y¨­u)®†è¢«‹‚€(g¨¨)查是否匹配规则。这意味着所有的匚w…å·¥ä½œž®†ä¼š(x¨¬)åœ?/span> assert 的过½E‹ä¸­å®Œæˆã€‚å°½½Ž¡å¦‚此,当你完成 assert facts 之后åQŒä½ ˜q˜è¦è°ƒç”¨â€?/span> fireAllRules() ”方法来执行规则ã€?/span>

当一个对象被 assert 后,ä¼?x¨¬)返回一ä¸?/span> FactHandle 。这ä¸?/span> FactHandle 是一个代表在 Working Memory 中你çš?/span> asserted Object çš„ä×o(h¨´)牌( token åQ‰ã€‚当你希æœ?/span> retract 或è€?/span> modify 一个对象的时候,˜q™ä¸ªä»¤ç‰Œè®©ä½ ç”¨æ¥å?/span> WorkingMemory ˜q›è¡Œäº¤äº’ã€?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );

WorkingMeomry 有两¿U?/span> assertion 模式åQ?/span> Equality å’?/span> Identity åQˆé»˜è®¤æ˜¯ Identity åQ‰ã€?/span>

Identity 模式ä¸?/span> WorkingMemory 使用一ä¸?/span> IdentityHashMap 来存储所有的 asserted Objects 。这个模式下åQŒå½“ asserted çš?/span> Object 是同一个实例时åQŒå®ƒ˜q”回同一ä¸?/span> FactHandle ã€?/span>

Equality 模式ä¸?/span> WorkingMemory 使用一ä¸?/span> HashMap 来存储所有的 asserted Objects 。这个模式下åQŒå½“ asserted çš?/span> Object 相等æ—Óž¼Œå®ƒè¿”回同一ä¸?/span> FactHandle ã€?/span>

åQ?/span> WorkingMemory.assertObject(yourObjcet) 只是˜q›è¡Œ assertion 的一¿U?/span> regular æ–ÒŽ(gu¨©)³•åQŒè¿˜å­˜åœ¨æœ‰ä¸€¿Uç§°ä¸?/span> logical assertion 的动作)(j¨ª)ã€?/span>

4.3 Retraction

基本上就æ˜?/span> assert 的逆操作。当ä½?/span> retract 一ä¸?/span> fact åQ?/span> WorkingMemory ž®†ä¸å†è·Ÿítªé‚£ä¸?/span> fact 。ä“Q何被 activated òq¶ä¾èµ–é‚£ä¸?/span> fact 的规则将被取消。注意:(x¨¬)完全有可能存在某条规则是依赖于一ä¸?/span> fact 的“不存在”( non existence åQ‰ã€‚在˜q™ç§æƒ…况下, retract 一ä¸?/span> fact ž®†å¯¼è‡´ä¸€æ¡è§„则被‹È€‹z…R€‚对一ä¸?/span> Fact ˜q›è¡Œ Retraction åQŒå¿…™åȝ”¨ assert 时返回的那个 FactHandle åšäØ“(f¨´)参数ã€?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );
.
workingMemory.retractObject( stiltonHandle );

4.4 Modification

当一ä¸?/span> Fact 被修改了(ji¨£n)åQŒä¼š(x¨¬)通知规则引擎˜q›è¡Œé‡æ–°å¤„理。在规则引擎内部实际上是å¯ÒŽ(gu¨©)—§çš?/span> Fact ˜q›è¡Œ retract åQŒç„¶åŽå¯¹æ–°çš„ Object 再进è¡?/span> assert 。要使用 modifyObject() æ–ÒŽ(gu¨©)³•来通知 Working Memory åQŒè¢«æ”¹å˜çš?/span> Object òq¶ä¸ä¼?x¨¬)自己通知规则引擎。注意:(x¨¬) modifyObject() æ–ÒŽ(gu¨©)³•æ€ÀL˜¯è¦æŠŠè¢«ä¿®æ”¹çš„ Object åšäØ“(f¨´)½W¬äºŒå‚æ•°åQŒè¿™ž®±å…è®æ€½ æŠŠä¸€ä¸ªä¸å¯å˜å¯¹è±¡æ›¿æ¢ä¸ºå¦ä¸€ä¸ªæ–°å¯¹è±¡ã€?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );
.
stilton.setPrice( 
100  );
workingMemory.modifyObject( stiltonHandle, stilton );

4.5 Globals

Global 是一个能够被传进 WorkingMemory 但不需è¦?/span> assert 的命名对象。大多数˜q™äº›å¯¹è±¡è¢«ç”¨æ¥ä½œä¸ºé™(r¨´n)态信息或服务。这些服务被用在一条规则的 RHS åQŒæˆ–者可能是从规则引擎返回对象的一¿Uæ–¹æ³•ã€?/span>

List list  =   new  ArrayListåQˆï¼‰(j¨ª);
workingMemory.setGlobal(
" list " , list);

setGlobal() æ–ÒŽ(gu¨©)³•ä¼ è¿›åŽÈš„命名对象必须å?/span> RuleBase 中所定义的具有相同的¾cÕdž‹åQˆå°±æ˜¯è¦åŒä½ çš„规则文件中ç”?/span> Global 关键字所定义的类型相同)(j¨ª)åQŒå¦åˆ™ä¼š(x¨¬)抛出一ä¸?/span> RuntimeException 。如果一条规则在ä½?/span> setGlobal 之前调用äº?ji¨£n)定义çš?/span> Global åQŒä¼š(x¨¬)抛出一ä¸?/span> NullPointerException ã€?/span>

4.6 Property Change Listener

如果你的 fact 对象æ˜?/span> JavaBean åQŒä½ å¯ä»¥ä¸ºå®ƒä»¬å®žçŽîC¸€ä¸?/span> property change listener åQŒç„¶åŽæŠŠå®ƒå‘Šè¯‰è§„则引擎。这意味着åQŒå½“一ä¸?/span> fact 改变æ—Óž¼Œè§„则引擎ž®†ä¼š(x¨¬)自动知道åQŒåƈ˜q›è¡Œå“åº”的动作(你不需要调ç”?/span> modifyObject() æ–ÒŽ(gu¨©)³•来通知 WorkingMemory åQ‰ã€?/span> Proxy libraries ž®†ä¼š(x¨¬)帮助实现˜q™ä¸€åˆ‡ã€‚要è®?/span> Property Change Listener 生效åQŒè¿˜è¦å°† fact 讄¡½®ä¸ºåŠ¨æ€ï¼ˆ dynamic åQ‰æ¨¡å¼ï¼Œé€šè¿‡ž®?/span> true åšäØ“(f¨´) assertObject() æ–ÒŽ(gu¨©)³•的第二个参数来实玎ͼš(x¨¬)

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton,  true  );   // specifies t hat this is a dynamic fact

然后要在 JavaBean 中加入一ä¸?/span> PropertyChangeSupport 实例åQŒå’Œä¸¤ä¸ªæ–ÒŽ(gu¨©)³•åQ?/span> addPropertyChangeListener() å’?/span> removePropertyChangeListener() 。最后要åœ?/span> JavaBean çš?/span> setter æ–ÒŽ(gu¨©)³•中通知 PropertyChangeSupport 所发生的变化。示例代码如下:(x¨¬)

private   final  PropertyChangeSupport changes  =   new  PropertyChangeSupport(  this  );

public   void  addPropertyChangeListener( final  PropertyChangeListener l) {
    
this .changes.addPropertyChangeListener( l );
}

public   void  removePropertyChangeListener( final  PropertyChangeListener l) {
    
this .changes.removePropertyChangeListener( l );
}

public   void  setState( final  String newState) {
    String oldState 
=   this .state;
    
this .state  =  newState;
this .changes.firePropertyChange(  " state " , oldState, newState );


5. Agenda:


Figure 5.1 . Agenda

Agenda æ˜?/span> RETE 的一个特炏V€‚在一ä¸?/span> WorkingMemory Action 发生æ—Óž¼Œå¯èƒ½ä¼?x¨¬)有多条规则发生完全匚w…ã€‚当一条规则完全匹配的时候,一ä¸?/span> Activation ž®Þp¢«åˆ›å¾åQˆå¼•用了(ji¨£n)˜q™æ¡è§„则和与其匹配的 facts åQ‰ï¼Œç„¶åŽæ”¾è¿› Agenda 中ã€?/span> Agenda 通过使用冲突解决½{–ç•¥åQ?/span> Conflict Resolution Strategy åQ‰æ¥å®‰æŽ’˜q™äº› Activations 的执行ã€?/span>

引擎工作在一个â€?/span> 2 阶段”模式下åQ?/span>

<!--[if !supportLists]--> 1åQ?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> WorkingMemory Actions åQ?/span>assertæ–°çš„factsåQŒä¿®æ”¹å­˜åœ¨çš„factså’?/span>retract facts都是WorkingMemory Actions。通过在应用程序中调用fireAllRules()æ–ÒŽ(gu¨©)³•åQŒä¼š(x¨¬)使引擎è{换到Agenda Evaluatioin阶段ã€?/span>

<!--[if !supportLists]--> 2åQ?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> Agenda Evaluation åQšå°è¯•选择一条规则进行激发(fireåQ‰ã€‚如果规则没有找到就退出,否则它就ž®è¯•‹È€å‘这条规则,然后转换åˆ?/span>WorkingMemory Actions阶段åQŒç›´åˆ?/span>Agenda䏭䨓(f¨´)½Iºã€?/span>

˜q™ä¸ª˜q‡ç¨‹ä¸€ç›´é‡å¤ï¼Œç›´åˆ° Agenda 是空的,此时控制权就回到应用½E‹åºä¸­ã€‚。当 WorkingMemory Actions 发生æ—Óž¼Œæ²¡æœ‰è§„则正在被激发ã€?/span>

下图说明äº?ji¨£n)这个åó@环的˜q‡ç¨‹åQ?/span>


Figure  5.2 . Two Phase Execution

5 åQ?/span> 1 Conflict Resultion

当有多条 rules åœ?/span> agenda 中,ž®±éœ€è¦è§£å†›_†²½Hã€‚当‹È€å‘一条规则时åQŒä¼š(x¨¬)å¯?/span> WorkingMemory 产生副作用。规则引擎需要知道规则要以什么顺序来‹È€å‘(例如åQŒæ¿€å?/span> rule A 可能ä¼?x¨¬)引è?/span> rule B 被从 agenda 中移除。)(j¨ª)

Drools 采取的冲½Hè§£å†³ç­–略有 2 ¿Uï¼ŒæŒ‰ç…§ä¼˜å…ˆ¾U§æŽ’列如下:(x¨¬) Salience åQ?/span> LIFO åQˆåŽ˜q›å…ˆå‡ºï¼‰(j¨ª)。最易懂的策略是â€?/span> Salience ”,即优先çñ”åQ?/span> user 可以为某ä¸?/span> rule 指定一个高一点的优先¾U§ï¼ˆé€šè¿‡é™„给它一个比较大的数字)(j¨ª)。高 Salience çš?/span> rule ž®†ä¼š(x¨¬)被优先激发ã€?/span>

5 åQ?/span> 2 Agenda Groups

Agenda Groups 是划åˆ?/span> Agenda ä¸?/span> rules åQˆå…¶å®žæ˜¯â€?/span> activations ”)(j¨ª)的一¿Uæ–¹æ³•。在ä»ÀL„ä¸€ä¸ªæ—¶åˆ»ï¼Œåªæœ‰ä¸€ä¸?/span> group 拥有â€?/span> focus ”,˜q™æ„å‘³ç€åªæœ‰åœ¨é‚£ä¸?/span> group 中的 activations 才是有效的ã€?/span>

Agenda Groups 是在 grouped rules 之间创徏一个“流”( flow åQ‰çš„½Ž€ä¾¿çš„æ–ÒŽ(gu¨©)³•。你可以在规则引擎中åQŒæˆ–是用 API 来切换具有焦点的¾l„。如果你的规则有很明¼‹®çš„多“阶ŒDµâ€ï¼ˆ phases åQ‰æˆ–多“序列”( sequences åQ‰çš„处理åQŒå¯ä»¥è€ƒè™‘ç”?/span> Agenda Groups 来达到这个目的ã€?/span>

每次调用 setFocus() æ–ÒŽ(gu¨©)³•的时候,那个 Agenda Group ž®×ƒ¼š(x¨¬)被压入一个堆栈,当这个有焦点的组为空æ—Óž¼Œå®ƒå°±ä¼?x¨¬)被弹出åQŒç„¶åŽä¸‹ä¸€ä¸ªç»„ž®×ƒ¼š(x¨¬)被执行。一ä¸?/span> Agenda Group 可以出现在堆栈的多个位置。默认的 Agenda Group 是â€?/span> MAIN ”,所有没有被指定 Agenda Group çš?/span> Activations 都被攑ֈ°é‚£ä¸ª¾l„中åQŒè¿™ä¸ªç»„æ€ÀL˜¯è¢«æ”¾åœ¨å †æ ˆçš„½W¬ä¸€ä¸ªç»„åQŒåƈ默认¾l™äºˆç„¦ç‚¹ã€?/span>

5 åQ?/span> 3  Agenda Filters


Figure 5.3. Agenda Filter

Filter 必须实现 AgendaFilter 接口åQŒç”¨æ¥å…è®¸æˆ–¼›æ­¢ä¸€ä¸?/span> activation 能够被激发ã€?/span> Drools 提供äº?ji¨£n)下面几¿Uæ–¹ä¾¿çš„默认实现åQ?/span>

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameEndWithAgendaFilter

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameEqualsAgendaFilter

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameStartsWithAgendaFilter

要ä‹É用一ä¸?/span> filter ž®Þp¦åœ¨è°ƒç”?/span> fireAllRules() æ–ÒŽ(gu¨©)³•的时候指定它。下面的例子ž®†å¯¹æ‰€æœ‰åå­—以â€?/span> Test ”结ž®„¡š„规则˜q›è¡Œ˜q‡æ×o(h¨´)åQ?/span>

workingMemory.fireAllRules(  new  RuleNameEndsWithAgendaFilter(  " Test "  ) );

6åQŽäº‹ä»¶æ¨¡åž‹ï¼ˆ Event Model åQ?/span>

Event 包里提供äº?ji¨£n)规则引擎的事äšg机制åQŒåŒ…括规则激发,对象è¢?/span> asserted ½{‰ç­‰ã€‚你可以使用事äšg机制来进è¡?/span> AOP ¾~–程ã€?/span>

有两¿Uç±»åž‹çš„ Event Listener åQ?/span> WorkingMemoryEventListener å’?/span> AgendaEventListener ã€?/span>


Figure 6.1. WorkingMemoryEventListener


Figure 6.2  AgendaEventListener

对两ä¸?/span> EventListener 接口都提供了(ji¨£n)默认实现åQŒä½†åœ¨æ–¹æ³•中òq¶æ²¡æœ‰åšä»ÖM½•事。你可以¾l§æ‰¿˜q™ä¸¤ä¸ªé»˜è®¤å®žçŽ°æ¥å®Œæˆä½ è‡ªå·Þqš„实现åQ?/span> DefaultAgendaEventListener å’?/span> DefaultWorkingMemoryEventListener 。下面代码说明了(ji¨£n)如何扩展一ä¸?/span> DefaultAgendaEventListner òq¶æŠŠå®ƒåŠ åˆ?/span> WorkingMemory 中,例子中只完成äº?/span> afterActivationFired() æ–ÒŽ(gu¨©)³•åQ?/span>

workingMemory.addEventListener(  new  DefaultAgendaEventListener() {                            
   
public   void  afterActivationFired(AfterActivationFiredEvent event) {
       
super .afterActivationFired( event );
       System.out.println( event );
   }
   
});

Drools 也提供了(ji¨£n) DebugWorkingMemoryEventListener å’?/span> DebugAgendaEventListener 两个实现¾c»ï¼Œåœ¨è¿™ä¸¤ä¸ª¾cÈš„æ–ÒŽ(gu¨©)³•中实çŽîCº†(ji¨£n) debug 信息的输出:(x¨¬)

workingMemory.addEventListener(  new  DebugWorkingMemoryEventListener() );




]]>
åQˆäºŒåQ? RETE½Ž—法 http://www.aygfsteel.com/clant/articles/85142.htmlBPM BPM Sun, 03 Dec 2006 01:53:00 GMThttp://www.aygfsteel.com/clant/articles/85142.htmlhttp://www.aygfsteel.com/clant/comments/85142.htmlhttp://www.aygfsteel.com/clant/articles/85142.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85142.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85142.htmlåœ?/font> JBoss Rules 学习(f¨¤n)åQˆä¸€åQ?什么是Rule 中,我们介绍äº?ji¨£n)JBoss Rules中对Rule的表½Cºï¼Œå…¶ä¸­æåˆ°äº?ji¨£n)JBoss Rule中主要采用的RETE½Ž—法来进行规则匹配。下面将详细的介¾lä¸€ä¸‹RETE½Ž—法在JBoss Rule中的实现åQŒæœ€åŽéšä¾¿æä¸€ä¸‹JBoss Rules中也可以使用的另一¿Uè§„则匹配算法Leapsã€?br />
1.Rete ½Ž—法 åQ?br />

Rete 在拉丁语中是 ”netâ€?/span> åQŒæœ‰¾|‘络的意思ã€?/span> RETE ½Ž—æ³•å¯ä»¥åˆ†äØ“(f¨´)两部分:(x¨¬)规则¾~–译åQ?/span> rule compilation åQ‰å’Œ˜qè¡Œæ—¶æ‰§è¡Œï¼ˆ runtime execution åQ‰ã€?/span>

¾~–译½Ž—法描述äº?ji¨£n)规则如何åœ?/span> Production Memory 中äñ”生一个有效的辨别¾|‘络。用一个非技术性的词来è¯ß_(d¨¢)¼Œä¸€ä¸ªèöL别网¾lœå°±æ˜¯ç”¨æ¥è¿‡æ»¤æ•°æ®ã€‚方法是通过数据在网¾lœä¸­çš„传播来˜q‡æ×o(h¨´)数据。在™å¶ç«¯èŠ‚ç‚¹ž®†ä¼š(x¨¬)有很多匹配的数据。当我们™åºç€¾|‘络向下赎ͼŒåŒšw…çš„æ•°æ®å°†ä¼?x¨¬)越来越ž®‘。在¾|‘络的最底部是终端节点( terminal nodes åQ‰ã€‚在 Dr Forgy çš?/span> 1982 òq´çš„论文中,他描˜qîCº†(ji¨£n) 4 ¿UåŸºæœ¬èŠ‚ç‚¹ï¼š(x¨¬) root , 1-input, 2-input and terminal 。下图是 Drools 中的 RETE 节点¾cÕdž‹åQ?/span>

 

Figure 1. Rete Nodes

根节点( RootNode åQ‰æ˜¯æ‰€æœ‰çš„对象˜q›å…¥¾|‘络的入口。然后,从根节点立即˜q›å…¥åˆ?/span> ObjectTypeNode ã€?/span> ObjectTypeNode 的作用是使引擎只做它需要做的事情。例如,我们有两个对象集åQ?/span> Account å’?/span> Order 。如果规则引擎需要对每个对象都进行一个周期的评估åQŒé‚£ä¼?x¨¬)浪费很多的旉™—´ã€‚䨓(f¨´)äº?ji¨£n)提高效率,引擎ž®†åªè®©åŒ¹é?/span> object type 的对象通过到达节点。通过˜q™ç§æ–ÒŽ(gu¨©)³•åQŒå¦‚果一个应ç”?/span> assert 一个新çš?/span> account åQŒå®ƒä¸ä¼š(x¨¬)ž®?/span> Order 对象传递到节点中。很多现ä»?/span> RETE 实现都有专门çš?/span> ObjectTypeNode 。在一些情况下åQ?/span> ObjectTypeNode 被用散列法进一步优化ã€?/span>

Figure 2 . ObjectTypeNodes

ObjectTypeNode 能够传播�/span> AlphaNodes, LeftInputAdapterNodes �/span> BetaNodes �/span>

1-input 节点通常被称ä¸?/span> AlphaNode ã€?/span> AlphaNodes 被用来评估字面条ä»Óž¼ˆ literal conditions åQ‰ã€‚虽ç„?d¨°ng)ž¼?/span> 1982 òq´çš„论文只提åˆîCº†(ji¨£n)相等条äšgåQˆæŒ‡çš„字面上相等åQ‰ï¼Œå¾ˆå¤š RETE 实现支持其他的操作。例如, Account.name = = “Mr Troutâ€? 是一个字面条件。当一条规则对于一¿U?/span> object type 有多条的字面条äšgåQŒè¿™äº›å­—面条件将被链接在一赗÷€‚这是说åQŒå¦‚果一个应ç”?/span> assert 一ä¸?/span> account 对象åQŒåœ¨å®ƒèƒ½åˆ°è¾¾ä¸‹ä¸€ä¸?/span> AlphaNode 之前åQŒå®ƒå¿…须先满­‘³ç¬¬ä¸€ä¸ªå­—面条件。在 Dr. Forgy 的论文中åQŒä»–ç”?/span> IntraElement conditions 来表˜q°ã€‚下面的图说明了(ji¨£n) Cheese çš?/span> AlphaNode ¾l„合åQ?/span> name = = “cheddarâ€?/span> åQ?/span> strength = = “strongâ€?/span> åQ‰ï¼š(x¨¬)


Figure 3. AlphaNodes

Drools 通过散列法优化了(ji¨£n)ä»?/span> ObjectTypeNode åˆ?/span> AlphaNode 的传播。每‹Æ¡ä¸€ä¸?/span> AlphaNode 被加åˆîC¸€ä¸?/span> ObjectTypeNode 的时候,ž®×ƒ»¥å­—面å€û|¼ˆ literal value åQ‰ä½œä¸?/span> key åQŒä»¥ AlphaNode ä½œäØ“(f¨´) value 加入 HashMap 。当一个新的实例进å…?/span> ObjectTypeNode 的时候,不用传递到每一ä¸?/span> AlphaNode åQŒå®ƒå¯ä»¥ç›´æŽ¥ä»?/span> HashMap 中获得正¼‹®çš„ AlphaNode åQŒé¿å…äº†(ji¨£n)不必要的字面‹‚€(g¨¨)查ã€?/span>

<!--[if !supportEmptyParas]-->

2-input 节点通常被称ä¸?/span> BetaNode ã€?/span> Drools 中有两种 BetaNode åQ?/span> JoinNode å’?/span> NotNode ã€?/span> BetaNodes 被用来对 2 个对象进行对比。这两个对象可以是同¿Uç±»åž‹ï¼Œä¹Ÿå¯ä»¥æ˜¯ä¸åŒ¾cÕdž‹ã€?/span>

我们¾U¦å®š BetaNodes çš?/span> 2 个输入称为左边( left åQ‰å’ŒåŒ™¾¹åQ?/span> right åQ‰ã€‚一ä¸?/span> BetaNode 的左边输入通常æ˜?/span> a list of objects 。在 Drools 中,˜q™æ˜¯ä¸€ä¸ªæ•°¾l„。右边输入是 a single object 。两ä¸?/span> NotNode 可以完成â€?/span> exists ’检查ã€?/span> Drools 通过ž®†çƒ¦(ch¨³)引应用在 BetaNodes 上扩展了(ji¨£n) RETE ½Ž—法。下囑ֱ•½CÞZº†(ji¨£n)一ä¸?/span> JoinNode çš„ä‹É用:(x¨¬)

Figure 4 . JoinNode


注意到图中的左边输入用到äº?ji¨£n)一ä¸?/span> LeftInputAdapterNode åQŒè¿™ä¸ªèŠ‚ç‚¹çš„ä½œç”¨æ˜¯å°†ä¸€ä¸?/span> single Object 转化ä¸ÞZ¸€ä¸ªå•对象数组åQ?/span> single Object Tuple åQ‰ï¼Œä¼ æ’­åˆ?/span> JoinNode 节点。因为我们上面提到过左边输入通常æ˜?/span> a list of objects ã€?/span>

<!--[if !supportEmptyParas]-->

Terminal nodes 被用来表明一条规则已¾låŒ¹é…äº†(ji¨£n)它的所有条ä»Óž¼ˆ conditions åQ‰ã€?/span> 在这点,我们说这条规则有äº?ji¨£n)一个完全匹配( full match åQ‰ã€‚在一些情况下åQŒä¸€æ¡å¸¦æœ‰â€œæˆ–”条件的规则可以有超˜q‡ä¸€ä¸ªçš„ terminal node ã€?/span>

Drools 通过节点的共享来提高规则引擎的性能。因为很多的规则可能存在部分相同的模式,节点的共享允许我们对内存中的节点数量˜q›è¡ŒåŽ‹ç¾ƒåQŒä»¥æä¾›éåŽ†èŠ‚ç‚¹çš„è¿‡½E‹ã€‚下面的两个规则ž®±å…±äº«äº†(ji¨£n)部分节点åQ?/span>

rule
    when
        Cheese( $chedddar : name 
==   " cheddar "  )
        $person : Person( favouriteCheese 
==  $cheddar )
    then
        System.out.println( $person.getName() 
+   "  likes cheddar "  );
end


rule
    when
        Cheese( $chedddar : name 
==   " cheddar "  )
        $person : Person( favouriteCheese 
!=  $cheddar )
    then
        System.out.println( $person.getName() 
+   "  does likes cheddar "  );
end

˜q™é‡Œæˆ‘们先不探讨˜q™ä¸¤æ?/span> rule 到的是什么意思,单从一个直观的感觉åQŒè¿™ä¸¤æ¡ rule 在它们的 LHS 中基本都是一æ ïL(f¨¥ng)š„åQŒåªæ˜¯æœ€åŽçš„ favouriteCheese åQŒä¸€æ¡è§„则是½{‰äºŽ $cheddar åQŒè€Œå¦ä¸€æ¡è§„则是不等äº?/span> $cheddar 。下面是˜q™ä¸¤æ¡è§„则的节点图:(x¨¬)

Figure 5 . Node Sharing

从图上可以看刎ͼŒ¾~–译后的 RETE ¾|‘络中, AlphaNode 是共享的åQŒè€?/span> BetaNode 不是å…׃ín的。上面说的相½{‰å’Œä¸ç›¸½{‰å°±ä½“现åœ?/span> BetaNode 的不同。然后这两条规则有各自的 Terminal Node ã€?/span>

<!--[if !supportEmptyParas]-->

RETE ½Ž—法的第二个部分是运行时åQ?/span> runtime åQ‰ã€‚当一个应ç”?/span> assert 一个对象,引擎ž®†æ•°æ®ä¼ é€’到 root node 。从那里åQŒå®ƒ˜q›å…¥ ObjectTypeNode òq¶æ²¿ç€¾|‘络向下传播。当数据匚w…ä¸€ä¸ªèŠ‚ç‚¹çš„æ¡äšgåQŒèŠ‚ç‚¹å°±ž®†å®ƒè®°å½•到相应的内存中。这样做的原因有以下几点åQšä¸»è¦çš„原因是可以带来更快的性能。虽然记住完全或部分匚w…çš„对象需要内存,它提供了(ji¨£n)速度和可伸羃性的特点。当一条规则的所有条仉™ƒ½æ»¡èƒöåQŒè¿™ž®±æ˜¯å®Œå…¨åŒšw…ã€‚而只有部分条件满­‘»I¼Œž®±æ˜¯éƒ¨åˆ†åŒšw…ã€‚(我觉得引擎在每个节点都有其对应的内存来储存满­‘Œ™¯¥èŠ‚ç‚¹æ¡äšg的对象,˜q™å°±é€ æˆäº?ji¨£n)如果一个对象是完全匚w…åQŒé‚£˜q™ä¸ªå¯¹è±¡ž®×ƒ¼š(x¨¬)在每个节点的对应内存中都存有其映象。)(j¨ª)

2. Leaps ½Ž—法åQ?/span>

Production systems çš?/span> Leaps ½Ž—法使用äº?ji¨£n)一¿Uâ€?/span> lazy ”方法来评估条äšgåQ?/span> conditions åQ‰ã€‚一¿U?/span> Leaps ½Ž—法的修改版本的实现åQŒä½œä¸?/span> Drools v3 的一部分åQŒå°è¯•结å?/span> Leaps å’?/span> RETE æ–ÒŽ(gu¨©)³•的最好的特点来处ç?/span> Working Memory 中的 facts ã€?/span>

古典çš?/span> Leaps æ–ÒŽ(gu¨©)³•ž®†æ‰€æœ‰çš„ asserted çš?/span> facts åQŒæŒ‰ç…§å…¶è¢?/span> asserted åœ?/span> Working Memory 中的™åºåºåQ?/span> FIFO åQ‰ï¼Œæ”‘Öœ¨ä¸Õd †æ ˆä¸­ã€‚它一个个的检æŸ?/span> facts åQŒé€šè¿‡˜q­ä»£åŒšw… data type çš?/span> facts 集合来找出每一个相兌™§„则的匚w…ã€‚当一个匹配的数据被发现时åQŒç³»¾lŸè®°ä½æ­¤æ—¶çš„˜q­ä»£ä½ç½®ä»¥å¤‡å¾…会(x¨¬)çš„ç‘ô¾l­è„P代,òq¶ä¸”‹È€å‘规则结果( consequence åQ‰ã€‚当¾l“æžœåQ?/span> consequence åQ‰æ‰§è¡Œå®Œæˆä»¥åŽï¼Œ¾pȝ»Ÿž®×ƒ¼š(x¨¬)¾l§ç®‹å¤„理处于ä¸Õd †æ ˆé¡¶éƒ¨çš„ fact 。如此反复ã€?/span>



]]>
åQˆä¸€åQ? 什么是Rule http://www.aygfsteel.com/clant/articles/85141.htmlBPM BPM Sun, 03 Dec 2006 01:52:00 GMThttp://www.aygfsteel.com/clant/articles/85141.htmlhttp://www.aygfsteel.com/clant/comments/85141.htmlhttp://www.aygfsteel.com/clant/articles/85141.html#Feedback0http://www.aygfsteel.com/clant/comments/commentRss/85141.htmlhttp://www.aygfsteel.com/clant/services/trackbacks/85141.html          学习(f¨¤n)JBoss Rules有几天了(ji¨£n)åQŒå› ä¸ø™¿™æ–šw¢çš„中文资料较?y¨­u)®‘,所以这几天都在看官¾|‘上的manual。这是一份不错的教程åQŒæˆ‘把我看的一些重要的东西¾˜»è¯‘整理äº?ji¨£n)一下,希望可以å¯ÒŽ(gu¨©)ƒ³å­¦ä¹ (f¨¤n)JBoss Rules的同学们提供一点帮助ã€?br />       在开始这份教½E‹ä¹‹å‰ï¼Œæˆ‘å…ˆ½Ž€è¦ä»‹¾lä¸€ä¸‹JBoss RulesåQ?br />       JBoss Rules 的前íw«æ˜¯Codehaus的一个开源项目叫Drools。最˜q‘被¾U›_…¥JBoss门下åQŒæ›´åäØ“(f¨´)JBoss RulesåQŒæˆä¸ÞZº†(ji¨£n)JBoss应用服务器的规则引擎ã€?br />       Droolsæ˜¯äØ“(f¨´)Java量èín定制的基于Charles  Forgyçš„RETE½Ž—法的规则引擎的实现。具有了(ji¨£n)OO接口的RETE,使得商业规则有了(ji¨£n)更自然的表达ã€?br /> 
       既然JBoss Rules是一个商业规则引擎,那我们就要先知道到底什么是RulesåQŒå³è§„则。在JBoss Rules中,规则是如何被表示çš?br />

Rules

      一条规则是对商业知识的¾~–码。一条规则有 attributes åQŒä¸€ä¸?/span> Left Hand Side åQ?/span> LHS åQ‰å’Œä¸€ä¸?/span> Right Hand Side åQ?/span> RHS åQ‰ã€?/span> Drools 允许下列几种 attributes åQ?/span> salience åQ?/span> agenda-group åQ?/span> no-loop åQ?/span> auto-focus åQ?/span> duration åQ?/font> activation-group ã€?/span>

rule �/span> < name > ”   �br />     < attribute >   < value >     
    when        
        
< LHS >     
    then        
        
< RHS >
end

      规则çš?/span> LHS ç”׃¸€ä¸ªæˆ–多个条äšgåQ?/span> Conditions åQ‰ç»„成。当所有的条äšgåQ?/span> Conditions åQ‰éƒ½æ»¡èƒöòq¶äØ“(f¨´)真时åQ?/span> RHS ž®†è¢«æ‰§è¡Œã€?/span> RHS 被称为结果( Consequence åQ‰ã€?/span> LHS å’?/span> RHS ¾cÖM¼¼äºŽï¼š(x¨¬)
if  (  < LHS >  ) {
    
< RHS >
}

      规则可以通过 package 关键字同一个命名空é—ß_(d¨¢)¼ˆ namespace åQ‰ç›¸å…Œ™”åQ›å…¶ä»–的规则引擎可能¿U°æ­¤ä¸ø™§„则集åQ?/span> Rule Set åQ‰ã€‚一ä¸?/span> package 声明äº?/span> imports åQ?/span> global 变量åQ?/span> functions å’?/span> rules ã€?/span>


package  com.sample

import  java.util.List
import  com.sample.Cheese

global List cheeses

function 
void  exampleFunction(Cheese cheese) {
    System.out.println( cheese );
}

rule “A Cheesy Rule�br />    when
        cheese : Cheese( type 
==   " stilton "  )
    then
        exampleFunction( cheese );
        cheeses.add( cheese );
end

      å¯ÒŽ(gu¨©)–°çš„æ•°æ®å’Œè¢«ä¿®æ”¹çš„æ•°æ®˜q›è¡Œè§„则的匹配称为模式匹配( Pattern Matching åQ‰ã€‚进行匹配的引擎¿UîCØ“(f¨´)推理机( Inference Engine åQ‰ã€‚被讉K—®çš„规则称ä¸?/span> ProductionMemory åQŒè¢«æŽ¨ç†æœø™¿›è¡ŒåŒ¹é…çš„æ•°æ®¿UîCØ“(f¨´) WorkingMemory ã€?/span> Agenda ½Ž¡ç†è¢«åŒ¹é…è§„则的执行。推理机所采用的模式匹配算法有下列几种åQ?/span> Linear åQ?/span> RETE åQ?/span> Treat åQ?/span> Leaps ã€?/span>

      Drools 采用äº?/span> RETE å’?/span> Leaps 的实现ã€?/span> Drools çš?/span> RETE 实现被称ä¸?/span> ReteOO åQŒè¡¨½C?/span> Drools å¯?/span> Rete ½Ž—法˜q›è¡Œäº?ji¨£n)加强和优化的实现ã€?/span>



      一条规则的 LHS ç”?/span> Conditional Element 和域¾U¦æŸåQ?/span> Field Constraints åQ‰ã€‚下面的例子昄¡¤ºäº?ji¨£n)对一ä¸?/span> Cheese Fact 使用äº?ji¨£n)字面域¾U¦æŸåQ?/span> Literal Field Constraint åQ?/span>

rule  " Cheddar Cheese "
    when
        Cheese( type 
==   " cheddar "  )
    then
        System.out.println( 
" cheddar "  );
end

上面的这个例子类ä¼égºŽåQ?/span>

public   void  cheddarCheese(Cheese cheese) {
    
if  ( cheese.getType().equals( " cheddar " ) {
        System.out.println( 
" cheddar "  );
    }
}
<!--[if !vml]--> <!--[endif]-->

      规则引擎实现äº?ji¨£n)æ•°æ®åŒé€»è¾‘çš„å®Œå…¨è§£è€¦ã€‚è§„åˆ™åÆˆä¸èƒ½è¢«ç›´æŽ¥è°ƒç”¨ï¼Œå› äØ“(f¨´)它们不是æ–ÒŽ(gu¨©)³•或函敎ͼŒè§„则的激发是å¯?/span> WorkingMemory 中数据变化的响应。结果( Consequence åQŒå³ RHS åQ‰ä½œä¸?/span> LHS events 完全匚w…çš?/span> Listener ã€?/span>

å½?/span> rules 被加å…?/span> Productioin Memory 后, rules 被规则引擎用 RETE ½Ž—法分解成一个图åQ?/span>



      å½?/span> Facts è¢?/span> assert ˜q›å…¥ WorkingMemory 中后åQŒè§„则引擎找到匹配的 ObjectTypeNode åQŒç„¶åŽå°†æ­?/span> Fact ä¼ æ’­åˆîC¸‹ä¸€ä¸ªèŠ‚ç‚V€?/span> ObjectTypeNode 拥有一块内存来保存所有匹配的 facts 。在我们的例子中åQŒä¸‹ä¸€ä¸ªèŠ‚ç‚ÒŽ(gu¨©)˜¯ä¸€ä¸ªåŸŸ¾U¦æŸåQ?/span> Field Constraint åQ‰ï¼Œ type = = “cheddarâ€?/span> 。如果某ä¸?/span> Cheese 对象的类型不是â€?/span> cheddar ”,˜q™ä¸ª fact ž®†ä¸ä¼?x¨¬)被传播到网¾lœçš„下一个节炏V€‚如果是â€?/span> cheddar ”类型,它将被记录到 AlphaNode 的内存中åQŒåƈ传播到网¾lœçš„下一个节炏V€?/span> AlphaNode 是古å…?/span> RETE 术语åQŒå®ƒæ˜¯ä¸€ä¸ªå•输入 / 单输出的节点。最后通过 AlphaNode çš?/span> fact 被传播到 Terminal Node ã€?/span> Terminal Node 是最¾lˆèŠ‚ç‚¹ï¼Œåˆ°æ­¤æˆ‘ä»¬è¯´è¿™æ¡è§„åˆ™è¢«å®Œå…¨åŒšw…åQŒåƈ准备‹È€å‘ã€?/span>

      当一条规则被完全匚w…åQŒå®ƒòq¶æ²¡æœ‰ç«‹åˆ»è¢«‹È€å‘(åœ?/span> RETE 中是˜q™æ ·åQŒä½†åœ?/span> Leaps 中它ä¼?x¨¬)立刻被‹È€å‘)(j¨ª)。这条规则和与其匚w…çš?/span> facts ž®†æ¿€‹z»è¢«æ”‘Ö…¥ Agenda åQŒç”± Agenda 来负责安排激å?/span> Activations åQˆæŒ‡çš„æ˜¯ rule + the matched facts åQ‰ã€?/span>

下面的图很清楚的说明äº?/span> Drools 规则引擎的执行过½E‹ï¼š(x¨¬)


   数据è¢?/span> assert ˜q?/span> WorkingMemory 后,å’?/span> RuleBase 中的 rule ˜q›è¡ŒåŒšw…åQˆç¡®åˆ‡çš„说应该是 rule çš?/span> LHS åQ‰ï¼Œå¦‚果匚w…æˆåŠŸ˜q™æ¡ rule ˜qžåŒå’Œå®ƒåŒšw…çš„æ•°æ®ï¼ˆæ­¤æ—¶ž®±å«å?/span> Activation åQ‰ä¸€èµ¯‚¢«æ”‘Ö…¥ Agenda åQŒç­‰å¾?/span> Agenda 来负责安排激å?/span> Activation åQˆå…¶å®žå°±æ˜¯æ‰§è¡?/span> rule çš?/span> RHS åQ‰ï¼Œä¸Šå›¾ä¸­çš„菱åŞ部分ž®±æ˜¯åœ?/span> Agenda 中来执行的, Agenda ž®×ƒ¼š(x¨¬)æ ÒŽ(gu¨©)®å†²çªè§£å†³½{–略来安æŽ?/span> Activation 的执行顺序ã€?/span>



]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ãèÂÞÊÐ| °²Ô¶ÏØ| áÓãôÏØ| ÎÂËÞÏØ| ÏæÌ¶ÊÐ| ºÚÉ½ÏØ| ¹ÅÝþÏØ| Ëì²ýÏØ| ¹ÌÊ¼ÏØ| ÄþÃ÷ÏØ| ¶¨ÖÝÊÐ| Æ½Ì¶ÏØ| ²©°®ÏØ| ÓͼâÍúÇø| É£Ö²ÏØ| Àû´¨ÊÐ| éŽ­ÏØ| º£¿ÚÊÐ| Ò×ÃÅÏØ| ͨ³ÇÏØ| ľÀï| Ó¦Óñر¸| ºôͼ±ÚÏØ| µÀæÚÏØ| ÁùÖ¦ÌØÇø| ÃÏÖÝÊÐ| ÊÖÓÎ| ÐÂÒ°ÏØ| °ÍÂí| ÖØÇìÊÐ| ËÄÆ½ÊÐ| ÁºÆ½ÏØ| Çì°²ÏØ| Ç­½­Çø| ºÚÉ½ÏØ| ÓÜÊ÷ÊÐ| ³£ÊìÊÐ| ³Ç¿ÚÏØ| »ªÆºÏØ| á¯ÏªÊÐ| ¸ÊÈªÏØ|