电竞比分网-中国电竞赛事及体育赛事平台

分享

Drools 5.1.1

 且看且珍惜 2014-04-12

第 8章 規(guī)則和流程

Drools流是一個工作流和流程的引擎,它允許高度集成流程和規(guī)則。本章討論規(guī)則和流程的集成,從簡單方案到高級方案。

8.1  為什么在流程中使用規(guī)則?

純 粹依賴流程結(jié)構(gòu)(如節(jié)點和線路)描述應(yīng)用程序業(yè)務(wù)邏輯的工作流(Workflow)語言往往是相當復(fù)雜。盡管這些工作流結(jié)構(gòu)很適合于描述一個應(yīng)用程序的整 個控制流,但是描述復(fù)雜邏輯和特殊情況卻相當困難。因此,可執(zhí)行的流程往往變得非常復(fù)雜。我們相信,通過擴展流程引擎,支持聲明式規(guī)則與這些標準流程結(jié)構(gòu) 的結(jié)合,這種復(fù)雜性可以得到控制。

  1. 簡單:復(fù)雜決策通常使用一組規(guī)則是更容易詳細說明。使用規(guī)則的高級約束語言,能夠更容易準確描述復(fù)雜的業(yè)務(wù)邏輯。描述業(yè)務(wù)邏輯的每一部分,都可以結(jié)合多條規(guī)則。
  2. 靈活: 規(guī)則和流程能夠有一個獨立的生命周期。這意味著我們可以改變描述某些關(guān)鍵決策點的規(guī)則,而不用改變流程本身。對不斷變化的需求和環(huán)境,可能添加、刪除和修改規(guī)則,微調(diào)流程的行為。 
  3. 不同的作用域:規(guī)則可以跨流程或者外部流程被重用。因此,你的業(yè)務(wù)邏輯沒有被鎖定在你的流程內(nèi)部。
  4. 聲明:關(guān)注描述“是什么”而不是“為什么”。
  5. 粒度:容易編寫處理具體情況的簡單規(guī)則。流程是更適合描述整個控制流,但是如果需要處理許多特殊情況,往往變得非常復(fù)雜。
  6. 數(shù)據(jù)為中心:規(guī)則能夠輕松處理大型數(shù)據(jù)集。
  7. 性能:規(guī)則的計算被優(yōu)化。
  8. 高級的條件和動作的語言:規(guī)則語言支持高級功能,如自定義函數(shù)、集合、條件元素、包括量詞(including quantifiers)等等。
  9. 高級別:通過使用DSLs、業(yè)務(wù)編輯器、決策表和決策樹,你的業(yè)務(wù)邏輯能夠以一種業(yè)務(wù)用戶可以理解(甚至可能編輯)的方式被描述。

8.2.  為什么在單個引擎中集成規(guī)則和流程?

  1. Drools流在一個軟件產(chǎn)品中合并了流程和規(guī)則。與現(xiàn)有的流程和規(guī)則產(chǎn)品相比較,它有幾個優(yōu)點 。
  2. 簡單:方便終端用戶合并規(guī)則和流程。.
  3. 封裝:有時候在流程和規(guī)則之間的緊密集成是有益的。
  4. 性能:沒有不必要的傳遞、轉(zhuǎn)換或數(shù)據(jù)的同步。
  5. 學(xué)習(xí)曲線:易于學(xué)習(xí)一個產(chǎn)品。
  6. 可管理性:易于管理一個產(chǎn)品,在一個更大型的知識信息庫中,規(guī)則和流程可以是類似的東西。
  7. 功能集成:我們提供了一個集成的IDE、審計記錄、基于網(wǎng)頁的管理、信息庫、調(diào)試等等。

8.3.  方法

工 作流語言描述了使用一個流程圖時應(yīng)該被執(zhí)行的活動的順序。流程引擎負責(zé)根據(jù)執(zhí)行流程的當前狀態(tài)選擇應(yīng)該執(zhí)行的活動。另一方面,規(guī)則是由描述什么時候可以應(yīng) 用一條規(guī)則的一組條件和在條件滿足時被執(zhí)行的一個動作構(gòu)成。然后規(guī)則引擎負責(zé)計算和執(zhí)行規(guī)則。它根據(jù)應(yīng)用程序的當前狀態(tài)決定需要被執(zhí)行的規(guī)則。

工作流流程擅長于描述應(yīng)用程序的整個控制流(可能是長期運行的)。然而,流程被用于定義復(fù)雜的業(yè)務(wù)決策,要處理許多特殊情況,和需要響應(yīng)各種外面事件,實事上往往變得非常復(fù)雜。規(guī)則擅長于描述復(fù)雜的決策和大量數(shù)據(jù)或事件的推理。但是不常使用規(guī)則來定義長期運行流程。

在過去,用戶被迫在使用流程或規(guī)則引擎定義他們的業(yè)務(wù)邏輯兩者間做選擇。關(guān)于大量數(shù)據(jù)需要推理的問題使用規(guī)則引擎,而用戶想關(guān)注描述他們流程的控制流則被迫使用流程引擎。然而,如今的業(yè)務(wù)可能希望合并流程和規(guī)則,以便于他們能夠以最適合的格式定義他們所有的業(yè)務(wù)邏輯。

基 本上,規(guī)則和流程引擎通過查看它的知識庫(一組規(guī)則或流程,各自的)和應(yīng)用程序的當前已經(jīng)狀態(tài)(在工作內(nèi)存中的數(shù)據(jù)或執(zhí)行流程的狀態(tài),各自的)得到需要被 執(zhí)行的下一個步驟。如果我們希望集成規(guī)則和流程,我們需要一個引擎,它可以就在流程和規(guī)則兩個內(nèi)部定義的邏輯決定下一個步驟。

8.3.1.  教給規(guī)則引擎有關(guān)流程

擴 展流程引擎,還把規(guī)則考慮在內(nèi)是非常困難(也可能是非常低效的)。流程引擎需要檢查在每一步都需要執(zhí)行的規(guī)則,并且必須保持規(guī)則引擎使用的最新數(shù)據(jù)。然 而,“教給”規(guī)則引擎有關(guān)流程是不困難的。如果當前的流程狀態(tài)也被作為工作內(nèi)存有關(guān)規(guī)則引擎推理數(shù)據(jù)的一部分插入,并且我們指示規(guī)則引擎如何得到一個執(zhí)行 流程的下一個步驟,那么規(guī)則引擎將能夠得到把規(guī)則和流程聯(lián)合考慮的下一個步驟。

8.3.2.  控制反轉(zhuǎn)

從流程的觀點看,這意味存在有一個控制反轉(zhuǎn)。常規(guī)的流程引擎行使完全控制,根據(jù)流程實例的當前狀態(tài)得到下一個步驟。如果需要,它能夠聯(lián)系外部服務(wù),檢索附加信息,但是它獨自決定要采取的步驟,并單獨負責(zé)執(zhí)行這些步驟。

然 而,只有我們擴展規(guī)則引擎(它能夠聯(lián)合規(guī)則和引擎推理)才能得到把規(guī)則和流程兩個聯(lián)合考慮的下一個步驟。如果需要執(zhí)行流程的一部分,規(guī)則引擎會請求流程引 擎執(zhí)行這個步驟。 一旦這個步驟已經(jīng)執(zhí)行,流程引擎返回控制給規(guī)則引擎,再得到下一個步驟。這意味著下一步該做什么已經(jīng)被反轉(zhuǎn):流程引擎自身不再決定要獲得的下一個步驟,但 是我們增加的規(guī)則引擎會控制、通知流程引擎在什么時候執(zhí)行什么東西。

8.4.  例子

 drools-examples項目包含了一個樣本流程(org.drools.examples.process.order),用于說明合并流程和規(guī)則的一些優(yōu)勢。 這個流程描述了一個訂單應(yīng)用程序,校驗進入的訂單、計算折扣和申請貨物航運。

8.4.1.   計算在你的流程中的一組規(guī)則

Drools流可以輕松地包括一組規(guī)則作為流程的一部分。需要被計算的規(guī)則,應(yīng)該使用ruleflow-group規(guī)則屬性,分組在一個規(guī)則流組中。
當 激活一個RuleSet 節(jié)點時,該分組觸發(fā)在你的進程中這些規(guī)則的計算。這個例子在流程中使用了兩個 RuleSet節(jié)點 :一個用于驗證訂單,一個用于計算折扣。例如,用于驗證訂單的規(guī)則之一,顯示如下。注意,ruleflow-group屬性,它確保這個規(guī)則作為具有下圖 中顯示了相同規(guī)則流組的RuleSet 節(jié)點的一部分被計算。

rule "Invalid item id" 

   ruleflow-group "validate" 

   lock-on-active true 

when

      o: Order()

      i: Order.OrderItem() from o.getOrderItems()

      not (Item() from itemCatalog.getItem(i.getItemId())) 

then 

      System.err.println("Invalid item id found!"); 

     o.addError("Invalid item id " + i.getItemId()); 

end

 

Drools 5.1.1_DOC (52) - *工* - 要有光,于是就有了光

 圖8.1. RuleSet節(jié)點和它的規(guī)則之一

8.4.2.  使用規(guī)則計算約束

可 以在你的流程中使用規(guī)則表達和計算復(fù)雜約束。例如,在一個Split節(jié)點決定執(zhí)行路徑的選擇時,可以使用規(guī)則來定義這些條件。相似的,一個 Wait 狀態(tài)可用一條規(guī)則來定義等待期限。這個例子使用規(guī)則決定在驗證訂單后的下一個動作。如果訂單包含錯誤,一個銷售代表應(yīng)該嘗試修正訂單。訂單的價格> 1000$ 是更重要的,那么一個高級代表應(yīng)該照料該訂單。所有其他訂單只應(yīng)該正常處理。 一個決定節(jié)點被用于選取這些選擇之一,并且規(guī)則被用來描述它們每一個的約 束。


Drools 5.1.1_DOC (52) - *工* - 要有光,于是就有了光
8.4.3.  分配( Assignment )規(guī)則

可以在一個流程中使用人類(Human)任務(wù),描述需要由人類參與者執(zhí)行的工作。 可以根據(jù)流程的當前狀態(tài)和歷史選擇參與者。分配規(guī)則描述了如何根據(jù)這些信息決定參與者。每當一個新的人類任務(wù)需要被執(zhí)行,那么這些分配規(guī)則會被自動應(yīng)用。

注意,顯示在下面的規(guī)則是用域特殊語言( Domain Specific Language -DSL)編寫,針對在訂單處理環(huán)境中的具體要求制定條件。

/********** Generic assignment rules **********/ 
   rule "Assign 'Correct Order' to any sales representative"
      salience 30
      when
          There is a human task
          - with task name "Correct Order"
          - without actor id
      then
           Set actor id "Sales Representative"
  end
 /********** Assignment rules for the RuleSetExample process **********/
    rule "Assign 'Follow-up Order' to a senior sales representative"
      salience 40
      when
          Process "org.drools.examples.process.ruleset.RuleSetExample" contains a human task
          - with task name "Follow-up Order" 
         - without actor id
      then
           Set actor id "Senior Sales Representative"
  end

8.4.4.   使用規(guī)則描述特殊情況

規(guī)則可以被用來描述特殊情況,以及如何響應(yīng)這些特殊情況。在正規(guī)流程的控制流中添加所有這些信息使基本流程變得更復(fù)雜。規(guī)則可以被用來分別處理各個這些情況,使核心流程保持簡單的格式。它也使它更容易適合現(xiàn)有的流程考慮先前未曾預(yù)料的事件。

8.4.5.  使用規(guī)則模塊化關(guān)注點

流 程定義了整個控制流。規(guī)則可以被用來為這個流程添加附加關(guān)注點,不必使整個控制流更復(fù)雜。例如,規(guī)則可以被用來記錄在流程執(zhí)行期間的某些信息。不改變原始 流程,而所有日志功能作為一組規(guī)則被清楚地模塊化。這極大地改善可重用性(允許用戶輕松地對不同的流程應(yīng)用相同的策略)、可讀性(不改變原始流程的控制 流)和可維護性(由于日志策略規(guī)則從那些流程本身的分離)。

8.4.6.  規(guī)則用于動態(tài)改變流程行為

規(guī) 則讓你動態(tài)地細調(diào)你的規(guī)則的行為。假設(shè)在運行期間有一個流程遭遇了一個問題?,F(xiàn)在,在運行期間,可以添加新規(guī)則,記錄附加信息或者處理特定流程的狀態(tài)。一 旦問題被解決或者環(huán)境已經(jīng)改變,這些規(guī)則可以輕松地再次被刪除。根據(jù)當前狀態(tài),可以動態(tài)地選擇不同的策略。例如,根據(jù)當前加載的所有服務(wù),規(guī)則可以被用于 為當前加載優(yōu)化流程。這個流程包含了一個簡單例子,允許你為 "Check Order"任務(wù)動態(tài)地增加或刪除日志。當在主應(yīng)用程序窗口中的"Debugging output"復(fù)選框被選取,只要"Check Order"任務(wù)被請求,規(guī)則顯示下面的動態(tài)加載,寫記錄輸出到控制臺。取消該框的選取,將動態(tài)地再次刪除規(guī)則

rule "Log the execution of 'Correct Order'"

      salience 25

when

      workItemNodeInstance: WorkItemNodeInstance( workItemId <= 0, node.name == "Correct Order" )

      workItem: WorkItemImpl( state == WorkItemImpl.PENDING ) from workItemNodeInstance.getWorkItem() 

then

      ProcessInstance proc = workItemNodeInstance.getProcessInstance(); 

     VariableScopeInstance variableScopeInstance =   (VariableScopeInstance)proc.getContextInstance( VariableScope.VARIABLE_SCOPE ); 

     System.out.println( "LOGGING: Requesting the correction of " +   variableScopeInstance.getVariable("order")); 

end

8.4.7.  集成工具

在Drools Eclipse IDE中集成了流程和規(guī)則。 流程和規(guī)則被簡單地看作業(yè)務(wù)邏輯的不同類型,管理幾乎是相同的。例如,加載一個流程或一組規(guī)則到引擎是非常相似的。另外,不同規(guī)則的實現(xiàn),如DRL或 DSL,都以統(tǒng)一的方式被處理。

private static KnowledgeBase createKnowledgeBase() throws Exception {

      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 

      kbuilder.add( ResourceFactory.newClassPathResource( 

                   "RuleSetExample.rf", OrderExample.class), ResourceType.DRF ); 

     kbuilder.add( ResourceFactory.newClassPathResource(

                    "workflow_rules.drl", OrderExample.class), ResourceType.DRL ); 

     kbuilder.add( ResourceFactory.newClassPathResource(

                    "assignment.dsl", OrderExample.class), ResourceType.DSL );

      kbuilder.add( ResourceFactory.newClassPathResource(

                   "assignment.dslr", OrderExample.class), ResourceType.DSLR );

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();

      kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

      return kbase;  }

 

我們的審計日志也包含一個集成視圖,顯示規(guī)則和流程序是如何相互影響。例如,日志的一部分,顯示了規(guī)則"5% discount" 如何被作為節(jié)點"Calculate Discount"的部分被執(zhí)行。


Drools 5.1.1_DOC (52) - *工* - 要有光,于是就有了光

8.4.8.  域特殊規(guī)則和流程

定義規(guī)則不需要使用核心規(guī)則語言的語法,而定義它們還可以使用我們更高級的規(guī)則編輯器,使用域特殊語言,決定表,向?qū)Ь庉嬈鞯鹊?。我們的例子定義了一個域特殊語言,用于根據(jù)任務(wù)的類型、它的屬性、定義它的流程等等描述分配規(guī)則。這使分配規(guī)則讓非專家人士更好理解。

/********** Generic assignment rules **********/ 

   rule "Assign 'Correct Order' to any sales representative"

      salience 30 

     when 

         There is a human task

          - with task name "Correct Order" 

          - without actor id

      then 

          Set actor id "Sales Representative"

  end

 

   /********** Assignment rules for the RuleSetExample process **********/

    rule "Assign 'Follow-up Order' to a senior sales representative"

      salience 40

     when

          Process "org.drools.examples.process.ruleset.RuleSetExample" contains a human task

          - with task name "Follow-up Order"

          - without actor id

      then

           Set actor id "Senior Sales Representative"

  end

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多