規(guī)則引擎 Easy Rules 使用實例(二)

簡書著作權歸作者所有秒咨,任何形式的轉載都請聯(lián)系作者獲得授權并注明出處但骨。

? ? ? ?在上一篇文章中創(chuàng)建規(guī)則引擎時道逗,用的是如下語句:

RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
RulesEngine fizzBuzzEngine = new DefaultRulesEngine(parameters);

? ? ? ?這里為規(guī)則引擎設置了一個屬性skipOnFirstAppliedRule砂沛,除了這一個屬性之外,規(guī)則引擎還有另外三個屬性哀澈,也就是說它一共有四個屬性牌借,即 rulePriorityThreshold、skipOnFirstAppliedRule割按、skipOnFirstFailedRule 和 skipOnFirstNonTriggeredRule走哺。其中 skipOnFirstFailedRule 屬性平時用到的比較少,因此我們這里不再贅述哲虾。下面我們通過實例來演示一下其他三個屬性的作用丙躏。
一、使用實例
? ? ? ?假設我們有這樣一個場景:
? ? (1)如果一個數(shù)字可以被 3 整除束凑,則輸出“three”晒旅;
? ? (2)如果一個數(shù)字在不滿足上面條件的情況下可以被 5 整除,則輸出“five”汪诉;
? ? (3)如果一個數(shù)字在均不滿足上面兩個條件的情況下可以被 7 整除废恋,則輸出“seven”;
? ? (4)如果一個數(shù)字均不滿足上述條件扒寄,則輸出該數(shù)字本身鱼鼓。

二、規(guī)則文件的文件名為 rules.yml 该编,其內(nèi)容如下:

---
name: "three"
description: "print three"
priority: 0
condition: "number % 3 == 0"
actions:
 - "System.out.println(\"three\")"
 
---
name: "five"
description: "print five"
priority: 1
condition: "number % 5 == 0"
actions:
 - "System.out.println(\"five\")"
 
---
name: "seven"
description: "print seven"
priority: 2
condition: "number % 7 == 0"
actions:
 - "System.out.println(\"seven\")"
 
---
name: "itself"
description: "print the number itself otherwise"
priority: 3
condition: "true"
actions:
 - "System.out.println(number)"

1迄本、客戶端調(diào)用代碼——不設置任何屬性的規(guī)則引擎

public class RuleClient {

    public static void main(String[] args) throws FileNotFoundException {
        RulesEngine rulesEngine = new DefaultRulesEngine();
        Rules rules = MVELRuleFactory.createRulesFrom(new FileReader("rules.yml"));

        Facts facts = new Facts();
        for (int i = 1; i <= 20; i++) {
            System.out.println("====== " + i + " ======");
            facts.put("number", i);
            rulesEngine.fire(rules, facts);
        }
    }
}

執(zhí)行結果如下:

====== 1 ======
1
====== 2 ======
2
====== 3 ======
three
3
====== 4 ======
4
====== 5 ======
five
5
====== 6 ======
three
6
====== 7 ======
seven
7
====== 8 ======
8
====== 9 ======
three
9
====== 10 ======
five
10
====== 11 ======
11
====== 12 ======
three
12
====== 13 ======
13
====== 14 ======
seven
14
====== 15 ======
three
five
15
====== 16 ======
16
====== 17 ======
17
====== 18 ======
three
18
====== 19 ======
19
====== 20 ======
five
20

過程分析:
? ? ? ?由于在創(chuàng)建規(guī)則引擎時沒有給其設置任何屬性,所以客戶端中每一個被 put 到 Facts 中的 number 都會對 .yml 文件中定義的所有規(guī)則按照優(yōu)先級從高到低的順序(priority的值越小课竣,則相應規(guī)則的優(yōu)先級越高)進行判斷嘉赎,并決定是否執(zhí)行相應的操作。
? ? ? ?比如于樟,數(shù)字 1 對于 .yml 文件中的所有規(guī)則按照優(yōu)先級從高到低的順序進行判斷公条,發(fā)現(xiàn)只滿足 priority 為 3 的那條規(guī)則,因此輸出了數(shù)字 1 本身迂曲。
? ? ? ?又比如靶橱,數(shù)字 15 滿足 priority 為 0 的那條規(guī)則,因此輸出了 “three”路捧,同時數(shù)字 15 還滿足 priority 為 1 的那條規(guī)則关霸,因此又輸出了 “five”,同時數(shù)字 15 還滿足 priority 為 3 的規(guī)則鬓长,因此還輸出了數(shù)字 15 本身谒拴。

2、客戶端調(diào)用代碼——設置了 skipOnFirstAppliedRule 屬性的規(guī)則引擎

public class RuleClient {

    public static void main(String[] args) throws FileNotFoundException {
        RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
        RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

        Rules rules = MVELRuleFactory.createRulesFrom(new FileReader("rules.yml"));

        Facts facts = new Facts();
        for (int i = 1; i <= 20; i++) {
            System.out.println("====== " + i + " ======");
            facts.put("number", i);
            rulesEngine.fire(rules, facts);
        }
    }
}

執(zhí)行結果如下:

====== 1 ======
1
====== 2 ======
2
====== 3 ======
three
====== 4 ======
4
====== 5 ======
five
====== 6 ======
three
====== 7 ======
seven
====== 8 ======
8
====== 9 ======
three
====== 10 ======
five
====== 11 ======
11
====== 12 ======
three
====== 13 ======
13
====== 14 ======
seven
====== 15 ======
three
====== 16 ======
16
====== 17 ======
17
====== 18 ======
three
====== 19 ======
19
====== 20 ======
five

過程分析:
? ? ? ?skipOnFirstAppliedRule 屬性的作用是涉波,客戶端中每一個被 put 到 Facts 中的 number 都會對 .yml 文件中定義的所有規(guī)則按照優(yōu)先級從高到低的順序進行判斷英上,當發(fā)現(xiàn)一個滿足條件的規(guī)則并執(zhí)行了相關操作后,便不再繼續(xù)判斷其他規(guī)則啤覆。如數(shù)字 10苍日,先對 priority 為 0 的規(guī)則進行判斷,發(fā)現(xiàn)不滿足該規(guī)則的條件窗声,于是繼續(xù)判斷 priority 為 1 的規(guī)則相恃,發(fā)現(xiàn)滿足該規(guī)則的條件,于是輸出“five”笨觅。至此拦耐,數(shù)字 10 便不會在理會 priority 為 2 和 priority 為 3 的規(guī)則耕腾,因此對于數(shù)字 10,其只輸出了“five”杀糯。

3扫俺、客戶端調(diào)用代碼——設置了 skipOnFirstNonTriggeredRule 屬性的規(guī)則引擎

public class RuleClient {

    public static void main(String[] args) throws FileNotFoundException {
        RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstNonTriggeredRule(true);
        RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

        Rules rules = MVELRuleFactory.createRulesFrom(new FileReader("rules.yml"));

        Facts facts = new Facts();
        for (int i = 1; i <= 20; i++) {
            System.out.println("====== " + i + " ======");
            facts.put("number", i);
            rulesEngine.fire(rules, facts);
        }
    }
}

執(zhí)行結果如下:

====== 1 ======
====== 2 ======
====== 3 ======
three
====== 4 ======
====== 5 ======
====== 6 ======
three
====== 7 ======
====== 8 ======
====== 9 ======
three
====== 10 ======
====== 11 ======
====== 12 ======
three
====== 13 ======
====== 14 ======
====== 15 ======
three
five
====== 16 ======
====== 17 ======
====== 18 ======
three
====== 19 ======
====== 20 ======

過程分析:
? ? ? ?skipOnFirstNonTriggeredRule 屬性的作用是,客戶端中每一個被 put 到 Facts 中的 number 都會對 .yml 文件中定義的所有規(guī)則按照優(yōu)先級從高到低的順序進行判斷固翰,如果滿足當前的規(guī)則狼纬,則執(zhí)行相應的操作,直到遇到不滿足條件的規(guī)則為止骂际,并且也不會對其他規(guī)則進行判斷了疗琉。我們?nèi)匀灰詳?shù)字 15 為例說明一下,數(shù)字 15 對 .yml 文件中的所有規(guī)則按照優(yōu)先級從高到低的順序進行判斷歉铝,發(fā)現(xiàn)滿足 priority 為 0 和 priority 為 1 的兩個規(guī)則盈简,于是輸出了“three”和“five”,在接下來判斷 priority 為 2 的規(guī)則時犯戏,發(fā)現(xiàn)數(shù)字 15 并不滿足這條規(guī)則送火,于是不做任何操作,至此先匪,數(shù)字 15 也不會再理會 priority 為 3 的規(guī)則了种吸。

3、客戶端調(diào)用代碼——設置了 rulePriorityThreshold 屬性的規(guī)則引擎

public class RuleClient {

    public static void main(String[] args) throws FileNotFoundException {
        RulesEngineParameters parameters = new RulesEngineParameters().priorityThreshold(1);
        RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

        Rules rules = MVELRuleFactory.createRulesFrom(new FileReader("rules.yml"));

        Facts facts = new Facts();
        for (int i = 1; i <= 20; i++) {
            System.out.println("====== " + i + " ======");
            facts.put("number", i);
            rulesEngine.fire(rules, facts);
        }
    }
}

執(zhí)行結果如下:

====== 1 ======
====== 2 ======
====== 3 ======
three
====== 4 ======
====== 5 ======
five
====== 6 ======
three
====== 7 ======
====== 8 ======
====== 9 ======
three
====== 10 ======
five
====== 11 ======
====== 12 ======
three
====== 13 ======
====== 14 ======
====== 15 ======
three
five
====== 16 ======
====== 17 ======
====== 18 ======
three
====== 19 ======
====== 20 ======
five

過程分析:
? ? ? ?在創(chuàng)建規(guī)則引擎時呀非,我們將其屬性 rulePriorityThreshold 的值設置為了 1坚俗,這樣的設置后的效果相當于在定義的所有規(guī)則中將 priority > 1 的規(guī)則去掉,換種說法就是只考慮 priority 的值小于等于 1 的規(guī)則岸裙。

三猖败、決定將規(guī)則放在 .java 文件還是 .yml 文件中的一些建議
? ? ? ?從上一章的介紹中我們知道規(guī)則可以以 .java 文件或 .yml 文件的形式出現(xiàn),但選用哪種文件比較合適降允,我這里有些個人建議:
? ?(1)若將規(guī)則放在 .java 文件中恩闻,我們可以在 @Condition 模塊進行比較復雜的邏輯編程,然后返回 true 或 false 來決定是否執(zhí)行 @Action 模塊的操作剧董,同時如果需要幢尚,我們也可以很方便地在 @Action 模塊實現(xiàn)比較復雜的邏輯。所以翅楼,如果涉及比較復雜的邏輯推導時尉剩,我們選用將規(guī)則放入 .java 文件中可以在該 .java 文件中使用我們較為熟悉的 java 語言來進行相關的邏輯推導。但將這種復雜的邏輯放到 .yml 文件中去實現(xiàn)的話毅臊,對于經(jīng)驗不是很豐富的人員來說可能是一種折磨鸟悴。
? ?(2)若在業(yè)務邏輯中只需要通過簡單地判斷就能得出相應的布爾值狂丝,且 Action 模塊的邏輯也比較簡單的話稍走,可以考慮將這些規(guī)則放入 .yml 文件中,這樣可以使得規(guī)則文件的內(nèi)容更加緊湊和明了朗鸠。

注意:以上建議僅供參考,具體選擇哪種方式以實際的應用場景為準來選擇式撼。

補充:
? ?? ?1童社、在規(guī)則文件中,不同的規(guī)則也可以設置相同的優(yōu)先級著隆,這是語法允許的。
? ?? ?2呀癣、在創(chuàng)建規(guī)則引擎并為其設置屬性時美浦,可以同時設置多個,例如:

RulesEngineParameters parameters = new RulesEngineParameters()
                .priorityThreshold(10)
                .skipOnFirstAppliedRule(true)
                .skipOnFirstFailedRule(true)
                .skipOnFirstNonTriggeredRule(true);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

? ?? ?3项栏、在設置了規(guī)則引擎的屬性后浦辨,在程序接下來的某個階段如果需要改變該引擎的屬性,可以先得到該引擎的屬性沼沈,然后再重新設置屬性值流酬。得到規(guī)則引擎屬性的方式如下:

RulesEngineParameters parameters = myEngine.getParameters();

相關文檔

Easy Rules Wiki

上一篇:規(guī)則引擎 Easy Rules 使用實例(一)
下一篇:java 解析 xml 文件實例

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市列另,隨后出現(xiàn)的幾起案子芽腾,更是在濱河造成了極大的恐慌,老刑警劉巖页衙,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摊滔,死亡現(xiàn)場離奇詭異,居然都是意外死亡店乐,警方通過查閱死者的電腦和手機艰躺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眨八,“玉大人腺兴,你說我怎么就攤上這事×啵” “怎么了页响?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伏穆。 經(jīng)常有香客問我拘泞,道長,這世上最難降的妖魔是什么枕扫? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任陪腌,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘诗鸭。我一直安慰自己染簇,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布强岸。 她就那樣靜靜地躺著锻弓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蝌箍。 梳的紋絲不亂的頭發(fā)上青灼,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音妓盲,去河邊找鬼杂拨。 笑死,一個胖子當著我的面吹牛悯衬,可吹牛的內(nèi)容都是我干的弹沽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼筋粗,長吁一口氣:“原來是場噩夢啊……” “哼策橘!你這毒婦竟也來了?” 一聲冷哼從身側響起娜亿,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤丽已,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后暇唾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體促脉,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年策州,在試婚紗的時候發(fā)現(xiàn)自己被綠了瘸味。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡够挂,死狀恐怖旁仿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情孽糖,我是刑警寧澤枯冈,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站办悟,受9級特大地震影響尘奏,放射性物質發(fā)生泄漏。R本人自食惡果不足惜病蛉,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一炫加、第九天 我趴在偏房一處隱蔽的房頂上張望瑰煎。 院中可真熱鬧,春花似錦俗孝、人聲如沸酒甸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽插勤。三九已至,卻和暖如春革骨,著一層夾襖步出監(jiān)牢的瞬間农尖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工苛蒲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卤橄,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓臂外,卻偏偏與公主長得像,于是被迫代替她去往敵國和親喇颁。 傳聞我的和親對象是個殘疾皇子漏健,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 這是2017.5.26的漫畫日記,一切如圖橘霎,不想多言
    雙玉雙魚閱讀 170評論 0 1
  • 1 人的記憶有時很奇怪蔫浆,一生中有很多重要事情,我都記不太清了姐叁,但是兩三歲時的記憶瓦盛,卻至今猶新。 可能那是為數(shù)不多的...
    大千一墨閱讀 550評論 2 8
  • 原文作者:Andrew Coyle 原文鏈接:Design Better Forms 無論是注冊流程外潜,多圖遞進原环,或...
    ShusQ閱讀 239評論 0 1
  • 我們語文老師是特級教師,我們每次周考月考后他都要花幾節(jié)課讓我們把標準答案寫上讓我們對照处窥,我們市前幾年語文單科138...
    春花秋實007閱讀 752評論 0 2