1. 程式人生 > >《Drools7.0.0.Final規則引擎教程》第4章 4.6 結果條件

《Drools7.0.0.Final規則引擎教程》第4章 4.6 結果條件

結果條件

在Java中,如果有重複的程式碼我們會考慮進行重構,抽取公共方法或繼承父類,以減少相同的程式碼在多處出現,達到程式碼的最優管理和不必要的麻煩。Drools同樣提供了類似的功能。下面我們以例項來逐步說明。
像下面最原始的兩條規則,有相同的業務判斷,也有不同的地方:

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional1:Give 10% discount to customers older than 60"
agenda-group "conditional1" when $customer : Customer( age > 60 ) then modify($customer) { setDiscount( 0.1 ) }; System.out.println("Give 10% discount to customers older than 60"); end rule "conditional1:Give free parking to customers older than 60" agenda-group "conditional1" when $customer : Customer( age > 60
) $car : Car ( owner == $customer ) then modify($car) { setFreeParking( true ) }; System.out.println("Give free parking to customers older than 60"); end

現在Drools提供了extends特性,也就是一個規則可以繼承另外一個規則,並獲得其約束條件。改寫之後執行效果相同,程式碼如下:

package com.rules.conditional
import com.secbro.drools.model.Customer
; import com.secbro.drools.model.Car; rule "conditional2:Give 10% discount to customers older than 60" agenda-group "conditional2" when $customer : Customer( age > 60 ) then modify($customer) { setDiscount( 0.1 ) }; System.out.println("conditional2:Give 10% discount to customers older than 60"); end rule "conditional2:Give free parking to customers older than 60" extends "conditional2:Give 10% discount to customers older than 60" agenda-group "conditional2" when $car : Car ( owner == $customer ) then modify($car) { setFreeParking( true ) }; System.out.println("conditional2:Give free parking to customers older than 60"); end

我們可以看到上面使用了extends,後面緊跟的是另外一條規則的名稱。這樣,第二條規則同時擁有了第一條規則的約束條件。只需要單獨寫此條規則自身額外需要的約束條件即可。那麼,現在是否是最優的寫法嗎?當然不是,還可以將兩條規則合併成一條來規則。這就用到了do和標記。

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional3:Give 10% discount to customers older than 60"
    agenda-group "conditional3"
when
    $customer : Customer( age > 60 )
    do[giveDiscount]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional3:Give free parking to customers older than 60");
then[giveDiscount]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("conditional3:Give 10% discount to customers older than 60");
end

在then中標記了giveDiscount處理操作,在when中用do來呼叫標記的操作。這樣也當第一個約束條件判斷完成之後,就執行標記giveDiscount中的操作,然後繼續執行Car的約束判斷,通過之後執行預設的操作。

在then中還可以新增一些判斷來執行標記的操作,這樣就不必每次都執行do操作,而是每當滿足if條件之後才執行:

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional4:Give 10% discount to customers older than 60"
    agenda-group "conditional4"
when
    $customer : Customer( age > 60 )
    if(type == "Golden") do[giveDiscount]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional4:Give free parking to customers older than 60");
then[giveDiscount]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("conditional4:Give 10% discount to customers older than 60");
end

同時,還可以通過break來中斷後續的判斷。

package com.rules.conditional
import com.secbro.drools.model.Customer;
import com.secbro.drools.model.Car;

rule "conditional5:Give 10% discount to customers older than 60"
    agenda-group "conditional5"
when
    $customer : Customer( age > 60 )
    if(type == "Golden") do[giveDiscount10]
    else if (type == "Silver") break[giveDiscount5]
    $car : Car(owner == $customer)
then
    modify($car) { setFreeParking(true) };
        System.out.println("conditional5:Give free parking to customers older than 60");
then[giveDiscount10]
    modify($customer){
        setDiscount(0.1)
    };
    System.out.println("giveDiscount10:Give 10% discount to customers older than 60");
then[giveDiscount5]
    modify($customer){
        setDiscount(0.05)
    };
    System.out.println("giveDiscount5:Give 10% discount to customers older than 60");
end

後語

此係列課程持續更新中,QQ群:593177274(可掃描左上側欄目二維碼),歡迎大家加入討論。點選連結關注《Drools部落格專欄》。由於Drools資料較少,教程編寫不易,每篇部落格都親身實踐編寫demo。如果對你有幫助也歡迎讚賞(微信)! 也是對原創的最大支援!
這裡寫圖片描述