Drools 快速指南



Drools - 簡介

任何 Java 企業級應用程式都可以分為三個部分:

  • UI - 使用者介面(前端)
  • 服務層,它又連線到資料庫
  • 業務層

我們有很多框架可以一起處理 UI 和服務層,例如 Spring 和 Struts。然而,在 Drools 出現之前,我們並沒有標準的方法來處理業務邏輯。

什麼是 Drools?

Drools 是一個**業務邏輯整合平臺 (BLiP)**。它是用 Java 編寫的。它是一個開源專案,由 JBoss 和 Red Hat, Inc. 支援。它擴充套件並實現了 Rete 模式匹配演算法。

簡單來說,Drools 是一組工具,允許我們分離和推理業務流程中發現的邏輯和資料。我們需要注意的兩個重要關鍵詞是**邏輯**和**資料**。

Drools 主要分為兩部分:**創作**和**執行時**。

  • **創作** - 創作過程涉及建立規則檔案(.DRL 檔案)。

  • **執行時** - 它涉及建立工作記憶體和處理啟用。

什麼是規則引擎?

Drools 是規則引擎或生產規則系統,它使用基於規則的方法來實現專家系統。專家系統是基於知識的系統,它使用知識表示將獲取的知識處理成可以用於推理的知識庫。

生產規則系統是圖靈完備的,它專注於知識表示,以簡潔、明確和宣告的方式表達命題邏輯和一階邏輯。

生產規則系統的核心是一個**推理引擎**,它可以擴充套件到大量的規則和事實。推理引擎將事實和資料與生產規則(也稱為**產生式**或僅稱為**規則**)進行匹配,以推斷導致行動的結論。

生產規則是一個兩部分的結構,它使用一階邏輯對知識表示進行推理。業務規則引擎是一個軟體系統,它在執行時生產環境中執行一個或多個業務規則。

規則引擎允許你定義“**做什麼**”,而不是“**如何做**”。

什麼是規則?

規則是知識片段,通常表達為:“_當_某些條件發生時,_則_執行某些任務。”

When
   <Condition is true>
Then
   <Take desired Action>

規則最重要的部分是它的**when**部分。如果**when**部分滿足,則觸發**then**部分。

rule  <rule_name>
   <attribute> <value>
      
   when
      <conditions>
      
   then
      <actions>
end

模式匹配

將新的或現有的事實與生產規則進行匹配的過程稱為模式匹配,它由推理引擎執行。有很多演算法用於模式匹配,包括:

  • 線性
  • Rete
  • Treat
  • Leaps

Drools 實現並擴充套件了 Rete 演算法。Drools 的 Rete 實現稱為 ReteOO,這表示 Drools 對面向物件的系統進行了 Rete 演算法的增強和最佳化實現。

規則引擎的優點

宣告式程式設計

規則使表達對複雜問題的解決方案並驗證解決方案變得容易。與程式碼不同,規則是用不太複雜的語言編寫的;業務分析師可以輕鬆閱讀和驗證一組規則。

邏輯和資料分離

資料駐留在領域物件中,業務邏輯駐留在規則中。根據專案的型別,這種分離可能非常有利。

速度和可擴充套件性

Drools 所基於的 Rete OO 演算法已經是一個經過驗證的演算法。藉助 Drools,您的應用程式變得非常可擴充套件。如果頻繁更改請求,可以新增新的規則而無需修改現有規則。

知識中心化

透過使用規則,您可以建立一個可執行的知識庫(知識庫)。它是業務策略的單一事實來源。理想情況下,規則的可讀性很高,也可以用作文件。

工具整合

Eclipse 等工具提供編輯和管理規則以及獲得即時反饋、驗證和內容輔助的方法。稽核和除錯工具也可用。

Drools - Eclipse 外掛

以下是安裝 Drools 外掛的先決條件:

  • Java 1.5(或更高版本)SE JDK
  • Eclipse 4.2(或任何版本)和 Drools 外掛

由於 Drools 是用 Java 編寫的 BRMS(業務規則管理系統),本節將介紹如何新增所需的外掛。考慮到大多數 Java 使用者使用 Eclipse,讓我們看看如何在 Eclipse 中新增 Drools 5.x.0 外掛。

步驟 1:下載二進位制檔案

從以下連結下載二進位制檔案:

https://download.jboss.org/drools/release/5.3.0.Final/

Binaries Download

下載完成後,將檔案解壓縮到您的硬碟。

步驟 2:安裝軟體

啟動 Eclipse 並轉到幫助→安裝新軟體。單擊“新增”,如下圖所示。

Available Software

然後,單擊此處顯示的“本地”,然後選擇“……/binaries/org.drools.updatesite”。

Add Repository

選擇 Drools 和 jBPM,然後單擊“下一步”。

Drools and jBPM

再次單擊“下一步”。然後,接受條款和許可協議,然後單擊“完成”。

Install Details

單擊“完成”後,軟體安裝開始:

Installation

安裝成功後,您將獲得以下對話方塊:

Software Updates

單擊“是”。Eclipse 重啟後,轉到 Windows → 首選項

Drools Runtime

您可以在首選項下看到 Drools。您的 Drools 外掛安裝現在已完成。

Drools - 執行時

Drools 執行時需要指示編輯器使用特定版本的 Drools jar 執行程式。您可以使用不同的 Drools 執行時執行您的程式/應用程式。

單擊 Windows → 首選項 → Drools → 已安裝的 Drools 執行時。然後單擊“新增”,如下圖所示。

Installed Drools Runtime

然後,單擊此處顯示的“建立新的 Drools 執行時”。

New Drools Runtime

輸入到您已下載 droolsjbpm-tools-distribution-5.3.0.Final.zip 的二進位制檔案資料夾的路徑。

單擊“確定”併為 Drools 執行時提供一個名稱。Drools 執行時現在已建立。

Drools - 建立 Drools 程式

要建立一個基本的 Drools 程式,請開啟 Eclipse。轉到檔案→新建→專案。

Basic Drools Program

選擇 Drools 專案。為專案命名。例如,DroolsTest。

下一個螢幕提示您選擇要在第一個 Drools 專案中包含的一些檔案。

New Drools Project

選擇前兩個檔案。第一個檔案是 .drl 檔案(Drools 規則檔案),第二個檔案是用於載入和執行 HelloWorld 規則的 Java 類。

單擊“下一步”→“完成”。

Select Drools Runtime

單擊“完成”後,將在您的工作區中建立一個 專案。開啟 Java 類,然後右鍵單擊並作為 Java 應用程式執行。您將看到如下所示的輸出:

Result

接下來,我們將討論規則引擎中常用的術語。

Drools - 常見術語

規則

規則引擎的核心,您可以在其中指定條件(如果“a”,則“b”)。

事實

事實是規則將作用於的資料。從 Java 的角度來看,事實是 POJO(普通舊 Java 物件)。

會話

Drools 中的知識會話是觸發規則的核心元件。它是儲存所有規則和其他資源的知識會話。知識會話是從知識庫建立的。

為了使規則引擎工作,事實被插入到會話中,當條件滿足時,隨後的規則被觸發。會話有兩種型別:

  • 無狀態知識會話
  • 有狀態知識會話

議程

這是一個邏輯概念。議程是啟用等待被觸發的邏輯位置。

啟用

啟用是規則的**then**部分。啟用被放置在議程中,其中適當的規則被觸發。

Drools - 規則編寫

如果您檢視在 HelloWorld 專案(Sample.drl)中編寫的預設規則,則使用了許多我們將解釋的關鍵字。

Default Rule

Sample.drl

  • **包** - 每個規則都以包名稱開頭。包充當規則的名稱空間。包中的規則名稱必須唯一。規則中的包類似於 Java 中的包。

  • **匯入語句** - 您想要應用規則的事實需要匯入。例如,在上面的示例中為 com.sample.DroolsTest.Message;

  • **規則定義** - 它由規則名稱、條件和結果組成。Drools 關鍵字為**rule、when、then**和**end**。在上面的示例中,規則名稱為“Hello World”和“GoodBye”。**when**部分是兩個規則中的條件,**then**部分是結果。在規則術語中,**when**部分也稱為 LHS(左側),**then**部分也稱為 RHS(右側)。

現在讓我們來看一下用於載入 Drools 並執行規則的 Java 檔案中使用的術語。

知識庫

知識庫是一個介面,它管理規則、流程和內部型別的集合。它包含在包**org.drools.KnowledgeBase**中。在 Drools 中,這些通常稱為**知識定義**或**知識**。知識定義分組到**知識包**中。可以新增或刪除知識定義。知識庫的主要目的是儲存和重用它們,因為它們的建立成本很高。知識庫提供建立知識會話的方法。

知識會話

知識會話是從知識庫中檢索的。它是與 Drools 引擎互動的主要介面。知識會話可以有兩種型別:

  • 無狀態知識會話

  • 有狀態知識會話

無狀態知識會話

無狀態知識會話是一個無狀態會話,它構成了最簡單的用例,不使用推理。無狀態會話可以像函式一樣呼叫,將一些資料傳遞給它,然後接收一些結果。無狀態會話的常見示例包括:

  • 驗證

    • 這個人是否有資格獲得抵押貸款?

  • 計算

    • 計算抵押貸款保險費。

  • 路由和過濾

    • 將傳入的訊息(例如電子郵件)過濾到資料夾中。

    • 將傳入的訊息傳送到目的地

有狀態知識會話

有狀態會話的壽命更長,並允許隨著時間的推移進行迭代更改。有狀態會話的一些常見用例包括:

  • 監控

    • 股票市場監控和分析,用於半自動購買。

  • 診斷

    • 故障查詢,醫學診斷

  • 物流

    • 包裹追蹤和交付供應

知識構建器

KnoledgeBuilder 介面負責從知識定義(規則、流程、型別)構建 KnowledgePackage。它包含在包**org.drools.builder.KnowledgeBuilder**中。知識定義可以採用多種格式。如果構建有任何問題,KnowledgeBuilder 將透過這兩種方法報告錯誤:**hasErrors** 和 **getError**。

下圖解釋了這個過程

KnoledgeBuilder

在上面的例子中,因為我們採用的是無狀態知識會話的簡單示例,我們在會話中插入了事實,然後呼叫了fireAllRules()方法,您可以看到輸出。

對於有狀態知識會話,一旦規則被觸發,有狀態知識會話物件必須呼叫方法dispose()來釋放會話並避免記憶體洩漏。

Drools - 規則語法

正如您所看到的.drl(規則檔案)有其自身的語法,讓我們在本章中介紹規則語法的部分內容。

規則中的條件

一條規則可以包含許多條件和模式,例如:

  • Account (balance == 200)
  • Customer (name == “Vivek”)

上述條件檢查賬戶餘額是否為200或客戶姓名是否為“Vivek”。

規則中的變數

Drools中的變數名以美元符號($)開頭。

  • $account − Account( )
  • $account 是Account()類的變數

Drools可以處理所有原生Java型別,甚至列舉。

規則中的註釋

可以使用特殊字元#或//來標記單行註釋。

對於多行註釋,請使用以下格式:

/*
   Another line
   .........
   .........
*/

全域性變數

全域性變數是分配給會話的變數。它們可以出於各種原因使用,如下所示:

  • 用於輸入引數(例如,可以逐個會話自定義的常量值)。

  • 用於輸出引數(例如,報告——規則可以向全域性報告變數寫入一些訊息)。

  • 用於日誌記錄等服務的入口點,這些服務可在規則中使用。

規則中的函式

函式是一個便利特性。它們可用於條件和結論中。函式代表實用程式/輔助類的替代方案。例如:

function double calculateSquare (double value) {
   return value * value;
}

方言

方言指定在條件或結論中的任何程式碼表達式中使用的語法。它包括返回值、evals、內聯evals、謂詞、salience表示式、結論等等。預設值為Java。Drools目前支援另一種稱為MVEL的方言。預設方言可以在包級別指定,如下所示:

package org.mycompany.somePackage
dialect "mvel"

MVEL方言

MVEL是用於基於Java的應用程式的表示式語言。它支援欄位和方法/getter訪問。它基於Java語法。

優先順序 (Salience)

優先順序是規則語法的一個非常重要的特性。優先順序由衝突解決策略用於決定首先觸發哪個規則。預設情況下,它是主要標準。

我們可以使用優先順序來定義規則的觸發順序。優先順序有一個屬性,它接受任何返回int型別數字的表示式(正數和負數都是有效的)。值越高,衝突解決策略選擇該規則觸發的可能性就越大。

salience ($account.balance * 5)

預設優先順序值為0。我們在只為某些規則分配優先順序值時應記住這一點。

規則語法中還有許多其他特性/引數,但我們這裡只介紹了重要的部分。

規則結論關鍵字

規則結論關鍵字是在規則的“then”部分中使用的關鍵字。

  • Modify − 事實的屬性可以在規則的then部分中修改。

  • Insert − 基於某個條件,如果為真,則可以將新的事實插入到規則引擎的當前會話中。

  • Retract − 如果規則中特定條件為真,並且您不想對該事實採取任何其他操作,則可以從規則引擎中撤回該特定事實。

注意 − 在規則結論中使用條件邏輯(if語句)被認為是一種非常不好的做法。大多數情況下,應該建立一個新的規則。

Drools - Drools 程式示例

在本章中,我們將為以下問題陳述建立一個Drools專案:

根據城市和產品型別(城市和產品的組合),找出與該城市相關的當地稅。

我們的Drools專案將有兩個DRL檔案。這兩個DRL檔案將表示所考慮的兩個城市(Pune和Nagpur)和四種類型的產品(食品雜貨、藥品、手錶和奢侈品)。

  • 這兩個城市藥品的稅收均視為零。

  • 對於食品雜貨,我們假設Pune的稅收為2盧比,Nagpur的稅收為1盧比。

我們使用了相同的售價來演示不同的輸出。請注意,所有規則都在應用程式中被觸發。

這是一個用於儲存每個itemType的模型:

package com.sample;
import java.math.BigDecimal;
public class ItemCity {
   public enum City {
      PUNE, NAGPUR
   }
   public enum Type {
      GROCERIES, MEDICINES, WATCHES, LUXURYGOODS
   }
   private City purchaseCity;
   private BigDecimal sellPrice;
   private Type typeofItem;
   private BigDecimal localTax;
   
   public City getPurchaseCity() {
      return purchaseCity;
   }
   public void setPurchaseCity(City purchaseCity) {
      this.purchaseCity = purchaseCity;
   }
   public BigDecimal getSellPrice() {
      return sellPrice;
   }
   public void setSellPrice(BigDecimal sellPrice) {
      this.sellPrice = sellPrice;
   }
   public Type getTypeofItem() {
      return typeofItem;
   }
   public void setTypeofItem(Type typeofItem) {
      this.typeofItem = typeofItem;
   }
   public BigDecimal getLocalTax() {
      return localTax;
   }
   public void setLocalTax(BigDecimal localTax) {
      this.localTax = localTax;
   }
}

DRL檔案

如前所述,我們這裡使用了兩個DRL檔案:Pune.drl和Nagpur.drl。

Pune.drl

這是執行Pune市規則的DRL檔案。

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Pune Medicine Item"
   when
      item : ItemCity (purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Pune Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE,
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

Nagpur.drl

這是執行Nagpur市規則的DRL檔案。

// created on: Dec 26, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;

// declare any global variables here
dialect "java"
rule "Nagpur Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

rule "Nagpur Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(1.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

我們根據城市編寫了DRL檔案,因為它使我們能夠在以後新增新的城市時新增任意數量的規則檔案。

為了演示所有規則都從我們的規則檔案中觸發,我們使用了兩種商品型別(藥品和食品雜貨);藥品免稅,食品雜貨按城市徵稅。

我們的測試類載入規則檔案,將事實插入會話,併產生輸出。

Droolstest.java

package com.sample;

import java.math.BigDecimal;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import com.sample.ItemCity.City;
import com.sample.ItemCity.Type;

/* 
   *This is a sample class to launch a rule. 
*/

public class DroolsTest {
   public static final void main(String[] args) {
      try {
         // load up the knowledge base
         KnowledgeBase kbase = readKnowledgeBase();
         StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
         
         ItemCity item1 = new ItemCity();
         item1.setPurchaseCity(City.PUNE);
         item1.setTypeofItem(Type.MEDICINES);
         item1.setSellPrice(new BigDecimal(10));
         ksession.insert(item1);
         
         ItemCity item2 = new ItemCity();
         item2.setPurchaseCity(City.PUNE);
         item2.setTypeofItem(Type.GROCERIES);
         item2.setSellPrice(new BigDecimal(10));
         ksession.insert(item2);
         
         ItemCity item3 = new ItemCity();
         item3.setPurchaseCity(City.NAGPUR);
         item3.setTypeofItem(Type.MEDICINES);
         item3.setSellPrice(new BigDecimal(10));
         ksession.insert(item3);
         
         ItemCity item4 = new ItemCity();
         item4.setPurchaseCity(City.NAGPUR);
         item4.setTypeofItem(Type.GROCERIES);
         item4.setSellPrice(new BigDecimal(10));         
         ksession.insert(item4);
         
         ksession.fireAllRules();
         
         System.out.println(item1.getPurchaseCity().toString() + " " 
            + item1.getLocalTax().intValue());
         
         System.out.println(item2.getPurchaseCity().toString() + " "
            + item2.getLocalTax().intValue());
         
         System.out.println(item3.getPurchaseCity().toString() + " "
            + item3.getLocalTax().intValue());
         
         System.out.println(item4.getPurchaseCity().toString() + " "
            + item4.getLocalTax().intValue());
                            
      } catch (Throwable t) {
         t.printStackTrace();
      }
   }
   private static KnowledgeBase readKnowledgeBase() throws Exception {
      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
      kbuilder.add(ResourceFactory.newClassPathResource("Pune.drl"), ResourceType.DRL);
      kbuilder.add(ResourceFactory.newClassPathResource("Nagpur.drl"), ResourceType.DRL);
      KnowledgeBuilderErrors errors = kbuilder.getErrors();
      
      if (errors.size() > 0) {
         for (KnowledgeBuilderError error: errors) {
            System.err.println(error);
         }
         throw new IllegalArgumentException("Could not parse knowledge.");
      }
      KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
      kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
      return kbase;
   }
}

如果您執行此程式,其輸出將如下所示:

PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

對於Pune和Nagpur,當商品是藥品時,當地稅為零;而當商品是食品雜貨時,稅收則根據城市而定。可以在DRL檔案中為其他產品新增更多規則。這只是一個示例程式。

從DRL檔案呼叫外部函式

在這裡,我們將演示如何從DRL檔案中呼叫Java檔案中的靜態函式。

首先,在同一個包com.sample中建立一個類HelloCity.java

package com.sample;

public class HelloCity {
   public static void writeHello(String name) {
      System.out.println("HELLO " + name + "!!!!!!");
   }
}

然後,在DRL檔案中新增import語句以從DRL檔案呼叫writeHello方法。在下面的程式碼塊中,Pune.drl檔案中更改的部分以黃色突出顯示。

// created on: Dec 24, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;
 
import com.sample.HelloCity;

//declare any global variables here
dialect "java"

rule "Pune Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, 
         typeofItem == ItemCity.Type.MEDICINES)
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
      HelloCity.writeHello(item.getPurchaseCity().toString());
end

rule "Pune Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, 
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
end

再次執行程式,其輸出將如下所示:

HELLO PUNE!!!!!!
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

現在輸出中的差異以黃色標記,顯示了Java類中靜態方法的輸出。

呼叫Java方法的優點是我們可以用Java編寫任何實用程式/輔助函式,並從DRL檔案中呼叫它。

Drools - 除錯

除錯Drools專案的方法有很多種。在這裡,我們將編寫一個實用程式類來讓您知道哪些規則正在觸發或被觸發。

透過這種方法,您可以檢查Drools專案中觸發的所有規則。這是我們的實用程式類

Utility.java

package com.sample;
import org.drools.spi.KnowledgeHelper;

public class Utility {
   public static void help(final KnowledgeHelper drools, final String message){
      System.out.println(message);
      System.out.println("\nrule triggered: " + drools.getRule().getName());
   }
   public static void helper(final KnowledgeHelper drools){
      System.out.println("\nrule triggered: " + drools.getRule().getName());
   }
}

第一個方法help列印觸發的規則以及您可以透過DRL檔案作為String傳遞的一些額外資訊。

第二個規則helper列印特定規則是否被觸發。

我們在每個DRL檔案中添加了一個實用程式方法。我們還在DRL檔案(Pune.drl)中添加了匯入函式。在規則的then部分,我們添加了實用程式函式呼叫。修改後的Pune.drl如下所示。更改部分以藍色突出顯示。

修改後的Pune.drl

//created on: Dec 24, 2014
package droolsexample

//list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal;
import com.sample.HelloCity; 
import function com.sample.Utility.helper;

// declare any global variables here
dialect "java"
rule "Pune Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, 
         typeofItem == ItemCity.Type.MEDICINES)
   
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice()));
      HelloCity.writeHello(item.getPurchaseCity().toString()); 
      helper(drools);
end

rule "Pune Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.PUNE, 
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(2.0);
      item.setLocalTax(tax.multiply(item.getSellPrice())); 
      helper(drools);
end

同樣,我們在第二個DRL檔案(Nagpur.drl)中添加了另一個實用程式函式。以下是修改後的程式碼:

修改後的Nagpur.drl

// created on: Dec 26, 2014
package droolsexample

// list any import classes here.
import com.sample.ItemCity;
import java.math.BigDecimal; 
import function com.sample.Utility.help;

//declare any global variables here
dialect "java"

rule "Nagpur Medicine Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
         typeofItem == ItemCity.Type.MEDICINES)
   
   then
      BigDecimal tax = new BigDecimal(0.0);
      item.setLocalTax(tax.multiply(item.getSellPrice())); 
      help(drools,"added info");
end

rule "Nagpur Groceries Item"
   when
      item : ItemCity(purchaseCity == ItemCity.City.NAGPUR, 
         typeofItem == ItemCity.Type.GROCERIES)
   then
      BigDecimal tax = new BigDecimal(1.0);
      item.setLocalTax(tax.multiply(item.getSellPrice())); 
      help(drools,"info");
end

再次執行程式,它應該產生以下輸出:

info

rule triggered: Nagpur Groceries Item
added info

rule triggered: Nagpur Medicine Item

rule triggered: Pune Groceries Item
HELLO PUNE!!!!!!

rule triggered: Pune Medicine Item
PUNE 0
PUNE 20
NAGPUR 0
NAGPUR 10

呼叫了兩個實用程式函式,它顯示了特定規則是否被呼叫。在上面的例子中,所有規則都被呼叫,但在企業應用程式中,此實用程式函式對於除錯和找出特定規則是否被觸發非常有用。

在Eclipse中使用除錯透檢視

您可以在Drools應用程式執行期間除錯規則。您可以在規則的結論中新增斷點,每當在規則執行期間遇到這樣的斷點時,執行將暫時停止。然後,您可以像在Java應用程式中一樣檢查此時已知的變數,並使用Eclipse中提供的正常除錯選項。

要在DRL檔案中建立斷點,只需雙擊要在其中建立斷點的行即可。請記住,您只能在規則的then部分建立斷點。可以透過雙擊DRL編輯器中的斷點來刪除斷點。

應用斷點後,您需要將應用程式作為Drools應用程式進行除錯。只有當您的應用程式作為Drools應用程式進行除錯時,Drools斷點(DRL檔案中的斷點)才能工作。以下是您需要執行的操作:

Drools Application

將應用程式作為Drools應用程式除錯後,您將看到DRL檔案上的控制元件,如下面的螢幕截圖所示:

Eclipse Platform

您可以看到變數以及該除錯點處物件的當前值。此處同樣適用F6移至下一行和F8跳轉至下一個除錯點的相同控制元件。透過這種方式,您可以除錯Drools應用程式。

注意 − 直到Drools 5.x,只有當方言為MVEL時,Drools應用程式中的除錯透檢視才有效。

廣告
© . All rights reserved.