<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    The Spark of Thinking

    Focus on Eclipse Tools.

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      3 隨筆 :: 27 文章 :: 4 評論 :: 0 Trackbacks
    作者:保羅.布朗;greenbright
    原文地址:http://www.onjava.com/pub/a/onjava/2005/08/03/drools.html
    中文地址:http://www.matrix.org.cn/resource/article/44/44046_Drools+Framework+Business.html
    關鍵詞: Drools Framework Business


    大多數網絡及企業級Jave應用可以分為三部分:和用戶交互的前端,和后端系統(比如數據庫)交互的服務層和這兩部分之間的商務邏輯層。通常使用框架(像Struts, Cocoon, Spring, Hibernate, JDO, 和實體Beans)可以實現前端和后端的功能,但對于商務邏輯層卻沒有一個標準的構建方法。像EJB和Spring只能在高端實現商務邏輯構建,但卻不能組織代碼。如果我們使用在配置性,可讀性和重用性方面帶我們極大利益的框架代替那些紛繁復雜的if...then語句,那不是很好嗎?在其他領域我們已經驗證了這種利益。這篇文章建議使用Drools規則引擎作為框架來解決問題。

    下面的代碼是我們試圖避免的問題的例子。說明一個典型Java應用中的一些商務邏輯。
    if ((user.isMemberOf(AdministratorGroup)
    ??????&& user.isMemberOf(teleworkerGroup))
    ???? || user.isSuperUser(){??????
    ???????? // 更多對特殊案例的檢查
    ???????? if((expenseRequest.code().equals("B203")
    ?????????? ||(expenseRequest.code().equals("A903")
    ????????????????????????&&(totalExpenses<200)
    ????????????????&&(bossSignOff> totalExpenses))
    ?????????? &&(deptBudget.notExceeded)) {
    ?????????????? //付款
    ?????????? } else if {
    ?????????????? //檢查許多其他的條件
    ?????????? }
    } else {
    ???? //更多商務邏輯
    }


    我們都曾經歷過相類似或者更為復雜的商務邏輯。當試圖在Java中采用標準方法來實施商務邏輯時,就有很多問題隨之而來。
    ·????????如果商務人員提出需要在本已很難理解的代碼中加入另外一個表單("C987")怎么辦?一旦所有的最初開發人員都在開發中,你愿意成為一個維護人員嗎?
    ·????????如何確認這些規則的正確與否?對技術人員來說(從來不關注商務人員),檢查規則的正確性是非常困難的。那么,有什么方法論來測試商務邏輯那?
    許多應用有著類似的商務邏輯。如果其中一個規則發生了變化,我們能夠確認所有系統中的相關部分都要改變嗎?如果一個新應用使用了一些規則,但是也加入了一些新規則,我們需要徹底重寫邏輯嗎?
    ·????????商務邏輯嵌入在Java代碼中,每次哪怕是很小的改變都需要再編譯/再部署這些代碼,這些商務邏輯容易配置嗎?
    ·????????如果其他的(腳本)語言想平衡現有投資在商務規則邏輯中怎么辦?

    J2EE/EJB和倒置控制的框架(像Spring, Pico和Avalon)讓我們有能力在高端組織代碼。他們很提供很好的重用性,配置性和安全性,但卻不能替代上面例子中的“意大利面條式代碼”。理想地,無論我們選擇那個框架,不僅要和J2EE應用,而且要和通常Java編程(J2SE—標準版本)及廣泛使用的表現和持續性框架相一致。這種框架讓我們能夠做到:
    ·????????商務用戶很容易的讀和驗證商務邏輯。
    ·????????在應用中,商務規則是可重用的和可配置的。
    ·????????在重負荷下,框架是可擴展的和性能良好的。
    ·????????Java編程人員對已存在的前端(Struts, Spring)和后端框架(對象關系映射)很容易使用這種框架。

    另一個問題是在不同的應用中,組織頁面,數據庫訪問和商務邏輯的方法也是多種多樣的。我們的框架能夠處理這個問題,并能始終提升代碼的重用性。理想地,我們的應用使用“適用所有方式的框架”。以這種方式使用框架,能夠讓我們許多的應用構建的更好,讓我們可以僅關注那些對用戶更有價值的部分。

    規則引擎的營救

    如何解決這個問題那? 一個解決方案是使用規則引擎。規則引擎是組織商務邏輯的框架。它讓開發者集中精力在他們有把握的事情上,而不是在一些低級機制上作決定。
    通常,商務用戶對那些能讓他們理解是正確的事情感到更加舒服,相對于那些諸如用if...then 形式來表達的事情。你從商務專家那里聽到的一些事情如下
    ·????????“10A表單用于申請超過200歐元的花費.”
    ·????????“我們僅對數量1萬或超過1萬的交易提供分成.”
    ·????????“超過10m英鎊的采購需要公司總監的批準.”

    通過關注于商務用戶知道是正確的事情上,而不是怎樣用Jave代碼來表達它,上面的說明比以前我們的代碼例子要清楚的多。盡管他們已經很清楚了,我們仍然需要一種機制,將這些規則應用到商務用戶已知和作決定的事實中去。這種機制就是規則引擎。

    相關文章:
    在企業級Java應用中使用Drools
    企業級Java應用開發者在表現和持續層有很多好的框架可供選擇。但對于處在中間層的商務邏輯有好的框架嗎?你希望每次經理給你一個新的命令就不得不重編譯那些復雜的if ... then 意大利面條代碼嗎?這篇文章中,保羅布朗推薦的Drools的規則引擎或許是完成這類任務的最好選擇。

    Jave規則引擎

    JSR 94- javax.rules API制定了與規則引擎交互的通用標準,就像JDBC能夠與各種類型的數據庫交互。JSR-94并不是詳細說明實際規則到底是怎么寫的,而是最大限度的使用Java規則引擎來做這種詳細說明。
    ·????????Jess可能是最成熟的Java規則引擎,有很多好的工具(包括Eclipse)和文檔。然而它是一個商業產品,并且它的規則是以序言樣式符號寫的,這對許多Java編程者都是一個挑戰。
    ·????????Jena是開源框架,始于HP.它有規則引擎,并且對那些關注于語義的網頁特別支持。但它并不完全遵守JSR-94。
    ·????????Drools是完全遵守JSR-94的規則引擎。而且是Apache模式許可下的完全開源框架。它不僅用大家熟知的Java 和XML語法來表示規則,而且有很強的用戶和開發者團體。本文章中的例子中,我們將使用Drools。Drools使用像Java的語法,并且有最開放的許可。

    用Drools開始開發Java應用

    想象一下這種情景:就在讀了這篇文章幾分鐘后,你的老板讓你給股票交易應用建原型。盡管商務用戶還沒有定義好商務邏輯,一個可以想到的好主意就是用規則引擎來實現。最終的系統將通過網絡訪問,并且需要和后端數據庫和信息系統交流。為了開始使用這個框架,需要下載Drools框架(有依賴性)。如圖1所示,在你喜歡的IDE中建一個新項目并確保所有的.jars文件都被引用了。

    image
    圖1。運行Drools必需的類庫

    由于潛在可能的巨大損失,如果我們的股票交易系統想要成功,在系統中循序漸進的使用一系列模擬器就顯得很重要。這樣的模擬器能夠讓你確信,即使規則改變了,由系統的作的決定也是正確的。我們將借用靈活工具箱的一些工具,并用JUnit框架作為模擬器。

    如下例所示,我們所寫的第一段代碼是Junit測試/模擬器。盡管我們不能測試所有輸入系統的值的組合,由測試總比什么都不測好。在這個例子中,所有的文檔和classes(包括單元測試)又在一個文件夾/包中;但事實上,由應該創建合適的包和文件夾結構。在代碼中,我們用Log4j代替System.out調用。

    清單1:
    import junit.framework.TestCase;
    /*
    * 應用中商務規則的JUnit測試
    ????????* 這也扮演商務規則的“模擬器“-讓我們說明輸入,檢驗輸出;并在代碼發*布前看看是否達到我的期望值。
    */
    public class BusinessRuleTest extends TestCase {
    /**
    *股票購買測試
    */
    ??public void testStockBuy() throws Exception{
    ????????????????
    //用模擬值創建股票
    ????StockOffer testOffer = new StockOffer();
    ????testOffer.setStockName("MEGACORP");
    ????testOffer.setStockPrice(22);
    ????testOffer.setStockQuantity(1000);
    ????????????????
    //運行規則
    ????BusinessLayer.evaluateStockPurchase(testOffer);
    ????????????????
    ????????//達到我們的期望嗎?
    ????assertTrue(
    ??????testOffer.getRecommendPurchase()!=null);
    ????
    ????assertTrue("YES".equals(
    ??????testOffer.getRecommendPurchase()));??????????????
    ?? }
    }


    這是個基本Junit測試,我們知道這個簡單系統應該買進所有價格低于100歐元的股票。很顯然,沒有數據類(StockOffer.java)和商務層類(BusinessLayer.java)這個測試用例是不能編譯成功的。

    清單2:
    /**
    *示例商務邏輯的正面
    *這個簡單示例里,所有的商務邏輯都包含在一個類中。
    *但在現實中,按需要代理給其他的類。
    */
    public class BusinessLayer {

    ????????/**
    ?? *評價購買這支股票是否是個好主意
    ?? *@參數 stockToBuy
    ?? *@return 如果推薦購買股票返回真,否則返回假
    ?? */
    ??public static void evaluateStockPurchase
    ????(StockOffer stockToBuy){
    ????????????????return false;
    ??}
    }
    StockOffer類如下所示:
    /**
    * 簡單的JavaBean保存StockOffer值。
    * 一個’股票出價’就是別人賣出股票(公司股份)所給出的價格。
    */
    public class StockOffer {
    ????????
    ??//常量
    ??public final static String YES="YES";
    ??public final static String NO="NO";

    ??//內部變量
    ??private String stockName =null;
    ??private int stockPrice=0;
    ??private int stockQuantity=0;
    ??private String recommendPurchase = null;

    /**
    ?? * @返回股票名稱
    ?? */

    ??public String getStockName() {
    ????????return stockName;
    ??}
    /**
    ?? * @參數 stockName 設置股票名稱.
    ?? */
    ??public void setStockName(String stockName) {
    ????????this.stockName = stockName;
    ??}
    /**
    ?? * @return 返回股票價格.
    ?? */

    ??public int getStockPrice() {
    ????????return stockPrice;
    ??}
    /**
    ?? * @參數 stockPrice設置股票價格.
    ?? */

    ??public void setStockPrice(int stockPrice) {
    ????????this.stockPrice = stockPrice;
    ??}
    /**
    ?? * @return 返回股票數量.
    ?? */

    ??public int getStockQuantity() {
    ????????return stockQuantity;
    ??}
    /**
    ?? * @參數 stockQuantity 設置股票數量.
    ?? */

    ??public void setStockQuantity(int stockQuantity){
    ????????this.stockQuantity = stockQuantity;
    ??}
    /**
    ?? * @return 返回建議購買.
    ?? */

    ??public String getRecommendPurchase() {
    ????????return recommendPurchase;
    ??}
    }


    在我們熟悉的IDE的Junit中運行BusinessRuleTest。如果你不太熟悉Junit,可以從Junit網站獲取更多信息。如圖2所示,毫不奇怪的是,由于沒有準備好適當的商務邏輯,測試在第二個申明處失敗了。這個確信了模擬器/單元測試重點加強了他們應該有的問題。

    image
    圖2。Junit測試結果

    用規則描述商務邏輯

    現在,我們需要描述一些商務邏輯,像“如果股票價格低于100歐元,應該購買?!?br />這樣我們將修改BusinessLayer.java為:

    清單3:
    import java.io.IOException;
    import org.drools.DroolsException;
    import org.drools.RuleBase;
    import org.drools.WorkingMemory;
    import org.drools.event.DebugWorkingMemoryEventListener;
    import org.drools.io.RuleBaseLoader;
    import org.xml.sax.SAXException;
    /**
    *示例商務邏輯的正面
    *這個簡單示例里,所有的商務邏輯都包含在一個類中。
    *但在現實中,按需要代理給其他的類。
    *@作者 缺省
    */
    public class BusinessLayer {
    //包含規則文件的名字
    ??private static final String BUSINESS_RULE_FILE=
    ??????????????????????????????"BusinessRules.drl";
    ????????//內部處理的規則基礎
    ??private static RuleBase businessRules = null;
    /**
    * 如果還沒有裝載商務規則的話就裝載它。
    *@拋出異常 -通常從這里恢復
    */
    ??private static void loadRules()
    ?????????????????????? throws Exception{
    ????if (businessRules==null){
    ??????businessRules = RuleBaseLoader.loadFromUrl(
    ??????????BusinessLayer.class.getResource(
    ??????????BUSINESS_RULE_FILE ) );
    ????}
    ??}????
    ????????
    /**
    ?? *評價是否購買這支股票
    ?? *@參數 stockToBuy
    ?? *@return 如果推薦購買股票返回真,否則返回假
    ?? *@拋出異常
    ?? */
    ??public static void evaluateStockPurchase
    ?????? (StockOffer stockToBuy) throws Exception{
    ????????????????
    //確保商務規則被裝載
    ????loadRules();
    //一些程序進行的日志
    ????System.out.println( "FIRE RULES" );
    ????System.out.println( "----------" );
    ????????//了解以前運行的狀態
    ????WorkingMemory workingMemory
    ????????????= businessRules.newWorkingMemory();
    //小規則集可以添加調試偵聽器
    ????workingMemory.addEventListener(
    ??????new DebugWorkingMemoryEventListener());
    ????????//讓規則引擎了解實情
    ????workingMemory.assertObject(stockToBuy);
    ????????//讓規則引擎工作
    ????workingMemory.fireAllRules();
    ??}
    }


    這個類有許多重要的方法:
    ·????????loadRules()方法裝載BusinessRules.drl文件中的規則。
    ·????????更新的evaluateStockPurchase()方法評價這些商務規則。這個方法中需要注意的是:
    ·????????同一個RuleSet可以被重復使用(內存中的商務規則是無狀態的)。
    ·????????由于以我們的知識我們知道什么是正確的,每次評價我們使用一個新的WorkingMemory類。在內存中用assertObject()方法存放已知的實事(作為Java對象)。
    ·????????Drools有一個事件偵聽模式,能讓我們“看到“事件模式內到底發生了什么事情。在這里我們用它打印出調試信息。Working memory類的fireAllRules()方法讓規則被評價和更新(在這個例子中,stock offer)。

    再次運行例子之前,我們需要創建如下BusinessRules.drl文件:

    清單4:
    <?xml version="1.0"?>
    <rule-set name="BusinessRulesSample"
    ??xmlns="http://drools.org/rules"
    ??xmlns:java="http://drools.org/semantics/java"
    ??xmlns:xs
    ????="http://www.w3.org/2001/XMLSchema-instance"
    ??xs:schemaLocation
    ????="http://drools.org/rules rules.xsd
    ??http://drools.org/semantics/java java.xsd">
    ??<!-- Import the Java Objects that we refer
    ??????????????????????????to in our rules -->????????
    ??<java:import>
    ????java.lang.Object
    ??</java:import>
    ??<java:import>
    ????java.lang.String
    ??</java:import>
    ??<java:import>
    ????net.firstpartners.rp.StockOffer
    ??</java:import>
    ??<!-- A Java (Utility) function we reference
    ????in our rules-->??
    ??<java:functions>
    ????public void printStock(
    ??????net.firstpartners.rp.StockOffer stock)
    ????????{
    ????????System.out.println("Name:"
    ??????????+stock.getStockName()
    ??????????+" Price: "+stock.getStockPrice()????
    ??????????+" BUY:"
    ??????????+stock.getRecommendPurchase());
    ????????}
    ??</java:functions>
    <rule-set>
    ??<!-- Ensure stock price is not too high-->??????
    ??<rule name="Stock Price Low Enough">
    ????<!-- Params to pass to business rule -->
    ????<parameter identifier="stockOffer">
    ??????<class>StockOffer</class>
    ????</parameter>
    ????<!-- Conditions or 'Left Hand Side'
    ????????(LHS) that must be met for
    ???????? business rule to fire -->
    ????<!-- note markup -->
    ????<java:condition>
    ??????stockOffer.getRecommendPurchase() == null
    ????</java:condition>
    ????<java:condition>
    ??????stockOffer.getStockPrice() < 100
    ????</java:condition>
    ????<!-- What happens when the business
    ??????????????????????rule is activated -->
    ????<java:consequence>
    ????????stockOffer.setRecommendPurchase(
    ??????????????????????????????StockOffer.YES);??
    ??????????printStock(stockOffer);
    ????</java:consequence>
    ??</rule>
    </rule-set>


    這個規則文件有幾個有意思的部分:
    ·????????在XML-Schema定義被引入Java對象后,我們也把它引入到我們的規則中。這些對象來自于所需的Java類庫。
    ·????????功能和標準的Java代碼相結合。這樣的話,我們就可以通過功能日志了解到底發生了什么。
    ·????????規則設置可以包括一個或多個規則。
    ·????????每條規則可以有參數(StockOffer類)。需要滿足一個或多個條件,并且當條件滿足時就執行相應的結果。

    修改,編譯了代碼后,再運行Junit測試模擬器。這次,如圖3所示,商務規則被調用了,邏輯評價正確,測試通過。祝賀—你已經創建了你的第一個基于規則的應用!

    image
    圖3。成功的Junit測試

    靈活的規則

    剛建好系統,你示范了上面的原型給商務用戶,這時他們想起先前忘了給你提到幾個規則了。新規則之一是當數量是負值時,不能夠交易股票。你說“沒問題,”,然后回到你的座位,借可靠的知識,你能迅速的改進系統。
    第一件要做的事情是更新你的模擬器,把下面的代碼加到BusinessRuleTest.java:

    清單5:

    /**
    *測試買股票確保系統不接受負值
    */
    ??public void testNegativeStockBuy()
    ????????????????????????????????throws Exception{
    //用模擬值創建股票
    ??????StockOffer testOffer = new StockOffer();
    ????????testOffer.setStockName("MEGACORP");
    ????????testOffer.setStockPrice(-22);
    ????????testOffer.setStockQuantity(1000);
    //運行規則
    ????????BusinessLayer
    ??????????????.evaluateStockPurchase(testOffer);
    //是否達到我們的期望?
    ????????assertTrue("NO".equals(
    ??????????testOffer.getRecommendPurchase()));
    }


    這是為商務用戶描述的新規則的測試。如果測試這個Junit測試,如預期的新測試失敗了。我們需要加這個新規則到.drl文件中,如下所示。

    清單6:
    <!-- Ensure that negative prices 
    ????????????????????????????are not accepted-->??????
    ??<rule name="Stock Price Not Negative">
    ????<!-- Parameters we can pass into
    ??????????????????????????the business rule -->
    ????<parameter identifier="stockOffer">
    ??????<class>StockOffer</class>
    ????</parameter>
    ????<!-- Conditions or 'Left Hand Side' (LHS)
    ?????? that must be met for rule to fire -->
    ????<java:condition>
    ??????stockOffer.getStockPrice() < 0
    ????</java:condition>
    ????<!-- What happens when the business rule
    ??????????????????????????????is activated -->
    ????<java:consequence>
    ??????stockOffer.setRecommendPurchase(
    ??????????????????????????????????StockOffer.NO);??????
    ??????printStock(stockOffer);
    ????</java:consequence>
    ??</rule>


    這個規則的和前一個類似,期望<java:condition>不同(測試負值)和<java:consequence>設置建議購買為No。再次運行測試/模擬器,這次測試通過。

    這樣的話,如果你習慣使用過程編程(象大多數Java 編程者),或許你會發愁撓頭:一個文件包含兩個獨立的商務規則,而且我們也沒有告訴規則引擎這兩個規則哪個更重要。然而,股票價格(-22)也符合兩個規則(它小于0也小于100)。不論如何,我們得到了正確的結果,即使交換規則的順序。這是怎么工作的那?

    下面控制臺輸出的摘錄幫助我們明白到底發生了什么。我們看到兩個規則都被觸發了([activationfired]行)并且Recommend Buy先被置為Yes然后被置為No。Drools是如何以正確的順序來觸發這些規則的那?如果你看Stock Price Low Enough規則,就會看到其中的一個條件recommendPurchase()是null.這就足以讓Drools決定Stock Price Low Enough規則應該先于Stock Price Not Negative規則觸發。這個過程就是沖突解決方案。

    清單7:
    FIRE RULES
    ----------
    [ConditionTested: rule=Stock Price Not Negative;
    ??condition=[Condition: stockOffer.getStockPrice()
    ??< 0]; passed=true; tuple={[]}]
    [ActivationCreated: rule=Stock Price Not Negative;
    ??tuple={[]}]
    [ObjectAsserted: handle=[fid:2];
    ?? object=net.firstpartners.rp.StockOffer@16546ef]
    [ActivationFired: rule=Stock Price Low Enough;
    ?? tuple={[]}]
    [ActivationFired: rule=Stock Price Not Negative;
    ?? tuple={[]}]
    Name:MEGACORP Price: -22 BUY:YES
    Name:MEGACORP Price: -22 BUY:NO


    如果你是個過程編程者,無論你認為這是多聰明,你仍然不能完全的信任它。這是為什么我們使用單元測試/模擬器:“辛苦的”Junit測試(使用通用Java代碼)保證規則引擎用我們關注的行來做決定。(不要花費上億在一些無價值的股票上?。┩瑫r,規則引擎的強大和靈活性讓我們能夠迅速開發商務邏輯。
    稍后,我們將看到更多沖突解決方案的經典的方式。

    沖突解決方案

    在商務這邊,人們真的印象深刻并別開始通過可能的選擇來思考。他們看到XYZ公司股票的問題并且決定執行一條新規則:如果XYZ公司的股價低于10歐元,就僅僅買XYZ公司的股票。
    象上次,加測試到模擬器中,在規則文件中加入新的商務規則,如下所列。首先,在BusinessRuleTest.java中添加新方法。

    清單8:
    /**
    *確保系統系統在XYZ公司股價便宜時就購買他們的股票
    */
    public void testXYZStockBuy() throws Exception{
    //用模擬值創建股票
    ??StockOffer testOfferLow = new StockOffer();
    ??StockOffer testOfferHigh = new StockOffer();
    ????????????????
    ??testOfferLow.setStockName("XYZ");
    ??testOfferLow.setStockPrice(9);
    ??testOfferLow.setStockQuantity(1000);
    ????????????????
    ??testOfferHigh.setStockName("XYZ");
    ??testOfferHigh.setStockPrice(11);
    ??testOfferHigh.setStockQuantity(1000);
    //運行規則
    ??BusinessLayer.evaluateStockPurchase(
    ????testOfferLow);
    ??assertTrue("YES".equals(
    ????testOfferLow.getRecommendPurchase()));
    ????????????????
    ??BusinessLayer.evaluateStockPurchase(
    ????testOfferHigh);
    ??assertTrue("NO".equals(
    ????testOfferHigh.getRecommendPurchase()));????????????
    }


    然后,在BusinessRules.drl中加個新<規則>:

    清單10:
    ??
    <rule name="XYZCorp" salience="-1">
    ?? <!-- Parameters we pass to rule -->
    ?? <parameter identifier="stockOffer">
    ???? <class>StockOffer</class>
    ?? </parameter>
    ????
    ?? <java:condition>
    ???? stockOffer.getStockName().equals("XYZ")
    ?? </java:condition>
    ?? <java:condition>
    ???? stockOffer.getRecommendPurchase() == null
    ?? </java:condition>
    ?? <java:condition>
    ???? stockOffer.getStockPrice() > 10
    ?? </java:condition>
    ????????
    ?? <!-- What happens when the business
    ????????????????????????????????rule is activated -->
    ?? <java:consequence>
    ???? stockOffer.setRecommendPurchase(
    ?????? StockOffer.NO);??
    ???? printStock(stockOffer);
    ?? </java:consequence>
    ??</rule>


    注意到商務規則文件中,規則名字后,我們設置salience為-1(比如,到現在我們說明的所有規則中的最低優先級)。系統沖突(意味著Drools在觸發那個規則的順序上作決定)的大多數規則給出了將達到的規則的條件。缺省的決定方法如下:.
    ·????????顯著性:如上列出的我們分配的值。
    ·????????嶄新性:我們使用規則的次數。
    ·????????復雜性:第一次觸發的更復雜的特定規則。
    ·????????裝載順序:那個規則被裝載的順序。
    如果我們不說明這個例子中規則的顯著性,將會發生的是:
    ·????????XYZ公司規則(“如果股票價格超過10歐元買XYZ”)將被首先觸發(推薦買標記的狀態被置為No)。
    ·????????然后是更多的普通規則被觸發(“買所有低于100的股票”),推薦買標記的狀態被置為yes。

    這將得到我們不期望的結果。然而,我們的例子設置了顯著性因素,用例及商務規則就會如我們期望的運行了。

    大多數情況下,書寫清楚的規則且設置顯著性將為Drools提供足夠的信息來選擇觸發規則的順序。有時,我們想整個的改變解決規則沖突的方式。以下是一個如何改變的例子,其中我告訴規則引擎首先觸發最簡單的規則。要注意的是,改變沖突解決方案是要小心,因為它能根本的改變規則引擎的規則—用清楚的寫得恰當的規則能預先解決許多問題。

    清單11:
    //生成沖突解決者的列表
    ??ConflictResolver[] conflictResolvers =
    ????new ConflictResolver[] {
    ??????SalienceConflictResolver.getInstance(),
    ??????RecencyConflictResolver.getInstance(),
    ????????SimplicityConflictResolver.getInstance(),
    ????????LoadOrderConflictResolver.getInstance()
    ????};
    //包裝成合成解決者
    ??CompositeConflictResolver resolver =
    ????new CompositeConflictResolver(
    ??????conflictResolvers);
    //當裝載規則時,說明這個解決者
    ??businessRules = RuleBaseLoader.loadFromUrl(
    ????BusinessLayer.class.getResource(
    ??????BUSINESS_RULE_FILE),resolver);


    對于我們的簡單的應用,由Junit測試驅動,我們不需要改變Drools解決規則沖突的方式。了解沖突解決方案是如何工作的對我們是非常有幫助的,尤其是當應用需要滿足更復雜根嚴格的需求試。

    結論

    這篇文章論證了許多編程者遇到過的問題:如何定制復雜的商務邏輯。我們示范了一個用Drools為解決方案的簡單應用并介紹了基于規則編程的概念,包括在運行時這些規則是如何被處理的。稍后,接下來的文章將以這些為基礎來展示在企業級Java應用中是如何使用它的。


    資源
    ·下載例子所有源代碼:源代碼
    ·Matrix-Java開發者社區:http://www.matrix.org.cn
    ·onjava.com:onjava.com
    ·Drools項目主頁
    ·Drools規則信息
    ·“Drools和規則引擎介紹”由Drools項目領導
    ·Drools規則計劃文件
    ·JSR-94, Java規則引擎,概略
    ·Jess Jave規則引擎
    ·Jena語義和規則引擎
    ·JSR-94主頁
    ·Jess在Action主頁
    ·“商務規則思想”(基于Jess)
    ·“規則系統的一般介紹”
    ·“Rete算法的Jess執行”

    保爾 布朗已經通過FirstPartners.net網站為企業級Java咨詢了約7年的時間。
    posted on 2006-07-21 16:58 The Spark of Thinking 閱讀(711) 評論(0)  編輯  收藏 所屬分類: Talk
    主站蜘蛛池模板: 亚洲免费观看视频| 一级毛片在线完整免费观看| 日本免费在线观看| 亚洲色精品vr一区二区三区| www免费插插视频| 亚洲综合无码精品一区二区三区 | 精品无码一区二区三区亚洲桃色| 中文字幕无线码中文字幕免费| 亚洲色欲久久久综合网| a级片免费观看视频| 亚洲VA中文字幕不卡无码| 中文字幕无码免费久久| 亚洲天堂男人天堂| 美女视频黄免费亚洲| 亚洲精品无码久久久久YW| 国产成人精品高清免费| 成人自慰女黄网站免费大全| 国产AV无码专区亚洲精品| 91久久青青草原线免费| 亚洲国产激情在线一区| 国产做床爱无遮挡免费视频| 精品一区二区三区免费观看| 亚洲成AV人片在线观看WWW| 久久精品免费一区二区| 亚洲欧美第一成人网站7777| 深夜国产福利99亚洲视频| 免费福利电影在线观看| 亚洲大片免费观看| 亚洲AV无码乱码在线观看| 成全高清在线观看免费| 亚洲综合av一区二区三区 | 久久噜噜噜久久亚洲va久| 91香蕉在线观看免费高清| 亚洲色成人四虎在线观看| av在线亚洲欧洲日产一区二区| 久久久精品午夜免费不卡| 亚洲欧洲日韩极速播放| 亚洲精品国产高清嫩草影院| 久久精品无码专区免费青青| 婷婷国产偷v国产偷v亚洲| 亚洲电影一区二区三区|