4.規則集
概述
規則集也叫決策集,在URule Pro當中是由一組普通(tōng)規則和(hé)循環規則構成的規則集合,是使用頻率最高(gāo)的一種業務規則實現方式。
在URule Pro中規則有(yǒu)兩種類型:一種是普通(tōng)規則;一種是循環規則。所謂的普通(tōng)規則是指一種由如果、那(nà)麽、否則三個(gè)部分構成的規則;而循環規則顧名思義就是可(kě)循環的規則,它允許指定一個(gè)集合類型的對象,對這個(gè)集合中每個(gè)對象進行(xíng)循環叠代,在循環體(tǐ)中則是若幹個(gè)由如果、那(nà)麽、否則構成的普通(tōng)規則。
在定義方式上(shàng),URule Pro提供了向導式規則集以及腳本式規則集定義兩種。
所謂向導式規則集是指利用引擎提供的設計(jì)器(qì),一步一步通(tōng)過鼠标點擊就可(kě)以完成其中的普通(tōng)規則與循環規則的配置,配合高(gāo)度可(kě)視(shì)化的向導式規則設計(jì)器(qì),可(kě)以最大(dà)限度将業務規則可(kě)視(shì)化,降低(dī)規則配置的複雜度;而腳本式規則集顧名思義就是通(tōng)過在規則集文件當中按URule Pro的腳本語法規範來(lái)書(shū)寫腳本實現普通(tōng)規則與循環規則的定義工作(zuò)。
向導式規則集因為(wèi)是圖形化,向導方式構建規則,所以适合業務人(rén)員使用;而腳本式規則集通(tōng)過書(shū)寫腳本構成規則,與傳統代碼編寫類似,所以适合技(jì)術(shù)人(rén)員來(lái)編寫規則;從功能上(shàng)看,向導式規則集和(hé)腳本式規則集能實現的功能是完全相同的,也就是說向導式規則集中能實現的功能在腳本式規則集也完全可(kě)以實現,反之亦然。
在URule Pro當中,雖然說腳本式規則能實現向導式規則中提供的所有(yǒu)功能,但(dàn)我們還(hái)是推薦大(dà)家(jiā)采用向導式規則集文件來(lái)定義我們的業務規則,原因很(hěn)簡單,向導式規則構建規則方式是可(kě)視(shì)化的,構建好的規則可(kě)讀性更好,這樣構建業務規則中出錯的機率就會(huì)更小(xiǎo)。
打開(kāi)一個(gè)URule Pro的項目,在“決策集”節點右鍵選擇創建一個(gè)向導式決策集文件,創建好的文件通(tōng)過URule Pro向導式決策集設計(jì)器(qì)打開(kāi)後的效果如下:
在向導式決策集的設計(jì)器(qì)中,通(tōng)過頂部的工具欄,點擊“添加規則”按鈕可(kě)以添加一個(gè)普通(tōng)的由如果、那(nà)麽、否則構成的普通(tōng)規則;點擊“添加循環規則”按鈕可(kě)以添加一個(gè)可(kě)以循環的規則。之前介紹的變量、常量、參數(shù)、動作(zuò)四種類型的庫文件,在向導式規則裏就可(kě)以導入使用了。
普通(tōng)規則
點擊“添加規則”按鈕就在下面的工作(zuò)區(qū)裏添加了一個(gè)普通(tōng)的規則,如下圖所示:
一個(gè)普通(tōng)規則主體(tǐ)是由如果、那(nà)麽、否則構成,點擊規則名可(kě)以對規則名進行(xíng)修改,修改完成後鼠标點擊頁簽處離開(kāi)焦點就完成了規則名的修改确認;點擊“添加屬性”鏈接可(kě)以為(wèi)當前規則定義相關屬性。無論是普通(tōng)規則還(hái)是循環規則都支持下面這些(xiē)屬性。
中文屬性名 | 英文屬性名 | 值類型 | 描述 |
---|---|---|---|
優先級 | salience | 數(shù)字 | 當有(yǒu)多(duō)個(gè)規則滿足條件時(shí),這個(gè)值用來(lái)決定這些(xiē)滿足條件規則中動作(zuò)的執行(xíng)順序,值越大(dà),執行(xíng)順序越靠前。如不設置這個(gè)值,那(nà)按條件滿足的順序執行(xíng),也就是說如果不配置優先級屬性規則的執行(xíng)順序是不确定的。 |
生(shēng)效日期 | effective-date | 字符串 | 當規則設置了生(shēng)效日期,表示這個(gè)規則隻有(yǒu)在當前系統日期為(wèi)大(dà)于等于生(shēng)效日期時(shí)才會(huì)生(shēng)效,否則即使條件滿足也不會(huì)觸發當前規則,如不設置,則不會(huì)對規則執行(xíng)産生(shēng)影(yǐng)響。該屬性的值要求是一個(gè)日期格式的字符串,格式為(wèi):yyyy-MM-dd HH:mm:ss |
失效日期 | expires-date | 字符串 | 與生(shēng)效日期對應,當規則設置失效日期時(shí),一旦當前系統日期大(dà)于或等于失效日期,即使條件滿足規則也不會(huì)觸發執行(xíng),如不設置,則不會(huì)對規則執行(xíng)産生(shēng)影(yǐng)響。屬性的值要求是一個(gè)日期格式的字符串,格式為(wèi):yyyy-MM-dd HH:mm:ss |
是否啓用 | enabled | 布爾值 | 默認值為(wèi)true,也就是啓用當前規則;如設置為(wèi)false,即使條件滿足規則也不會(huì)觸發執行(xíng),如不設置,則不會(huì)對規則執行(xíng)産生(shēng)影(yǐng)響。 |
允許調試信息輸出 | debug | 布爾值 | 默認為(wèi)false,表示不輸出調試信息,設置為(wèi)true後,規則在執行(xíng)時(shí)會(huì)在控制(zhì)台輸出規則條件的匹配信息、規則動作(zuò)的執行(xíng)信息;如果規則計(jì)算(suàn)過程出現異常,還(hái)會(huì)在控制(zhì)台輸出計(jì)算(suàn)出現異常的位置,以便于我們快速定義規則錯誤位置。需要注意的是,如果項目的urule.debug屬性設置為(wèi)false時(shí),規則的這個(gè)屬性會(huì)被覆蓋,也就是說即使設置為(wèi)true也不會(huì)輸出任何信息。 |
互斥組 | mutex-group | 字符串 | 系統會(huì)自動将此屬性相同的規則劃為(wèi)一組,且這個(gè)組中隻有(yǒu)一個(gè)規則會(huì)執行(xíng),待執行(xíng)的規則如設置了優先級,則優先級最高(gāo)的規則執行(xíng),否則随機;需要注意的是,互斥組屬性僅在當前規則集文件默認模式下有(yǒu)用,在順序模式下互斥組屬性将不起作(zuò)用。 |
執行(xíng)組 | pended-group | 字符串 | 系統會(huì)自動将此屬性相同的規則劃為(wèi)一組,默認情況下,引擎不會(huì)執行(xíng)這個(gè)組裏的規則,需要我們在定義規則動作(zuò)時(shí)利用系統內(nèi)置的函數(shù)顯示的指定要激活執行(xíng)的執行(xíng)組名,這樣系統才會(huì)嘗試匹配并執行(xíng)組裏的規則。 |
允許循環觸發 | loop | 布爾值 | 當執行(xíng)“更新工作(zuò)區(qū)對象”動作(zuò)時(shí),某些(xiē)規則可(kě)以會(huì)再次滿足條件,這時(shí)這個(gè)屬性就是用來(lái)決定這種類型的規則是否允許再次觸發執行(xíng)。關于“更新工作(zuò)區(qū)對象”請(qǐng)參考“更新工作(zuò)區(qū)“章節介紹 |
在使用過程當中,如果一個(gè)規則配置了執行(xíng)組,也配置了互斥組屬性,那(nà)麽這個(gè)規則對應的執行(xíng)組屬性被激活後,其中配置了互斥組屬性的規則将按互斥組屬性執行(xíng)原則執行(xíng)。
在向導式規則文件工具欄上(shàng)名為(wèi)配置的按鈕菜單下有(yǒu)一個(gè)用于控制(zhì)當前文件中所有(yǒu)向導式規則日志(zhì)輸出的開(kāi)關按鈕,它的默認狀态為(wèi)“禁用調試日志(zhì)輸出”,如果我們希望打開(kāi)當前文件中所有(yǒu)向導式規則的日志(zhì)輸出功能,那(nà)麽隻需要在這裏 将“禁用調試日志(zhì)輸出”改為(wèi)“允許調試日志(zhì)輸出”即可(kě)。
規則名及屬性定義完成後,接下來(lái)就可(kě)以開(kāi)始配置規則的主體(tǐ)部分,首先是“如果”部分,在如果部分當中可(kě)以添加若幹條件,添加完條件後,就可(kě)以通(tōng)過鼠标點擊以向導方式設置條件,如下圖:
對于一個(gè)具體(tǐ)的條件來(lái)說,我們可(kě)以将其分為(wèi)三個(gè)部分,分别是條件左邊部分、比較操作(zuò)符以及條件右邊部分。條件左邊部分,如上(shàng)圖所示我們可(kě)選擇的有(yǒu)變量、參數(shù)或者方法或函數(shù),當然這相應的需要我們導入相關的變量庫、參數(shù)庫以及方法庫;對于操作(zuò)符目前URule Pro當中提供了下面這些(xiē)操作(zuò)比較符,如下圖所示:
這些(xiē)操作(zuò)比較符基本已涵蓋我們業務當中所有(yǒu)類型的比較操作(zuò)。
大(dà)部分的比較操作(zuò)符比較簡單,這裏挑幾個(gè)看起來(lái)複雜一些(xiē)的比較操作(zuò)符介紹一下使用方式:
比較操作(zuò)符名稱 | 描述 |
---|---|
在集合中 | 判斷條件左值是不是在條件右值的對應的集合當中,條件右值可(kě)以是一個(gè)Collection類型的集合對象,也可(kě)以是一個(gè)由,分隔的字符串,比如aaa,bbb,ccc |
不在集合中 | 用法與“在集合中”剛好相反 |
匹配正則表達式 | 要求條件右值是一個(gè)标準的正則表達式,這裏需要指出的是條件中采用的正則匹配方式是字符串全匹配方式,不是部分匹配方式。比如條件左值為(wèi)字符串“我是中國人(rén)”,條件右值中輸入字符串“中國”,運行(xíng)時(shí)你(nǐ)會(huì)發現條件無法滿足,這是因為(wèi)條件右值中隻是部分匹配條件左值,改成“.*中國.*”後即變成全字符串匹配,表示左值中隻要包含“中國”字符串即可(kě)以匹配,具體(tǐ)使用大(dà)家(jiā)可(kě)參照标準的正則表達式語法 |
不匹配正則表達式 | 與“匹配正則表達式”作(zuò)用相反 |
在區(qū)間(jiān)值中 | 要求條件右值是一個(gè)由,分隔的兩個(gè)值,目前支持數(shù)字和(hé)日期兩種類型,如:“30,40”表示條件左值大(dà)于等于30且小(xiǎo)于等于40,如果條件左值是個(gè)日期,那(nà)麽條件右值可(kě)以寫成這樣:“2010-12-11,2020-12-11”,那(nà)就表示左值的日期要大(dà)于等于2010-12-11,同時(shí)要小(xiǎo)于等于2020-12-11(日期格式支持yyyy-MM-dd或yyyy-MM-dd HH:mm:ss兩種類型);定義區(qū)間(jiān)值時(shí)還(hái)可(kě)以使用[]和(hé)()來(lái)确定是否包含起始值,其中[]是包含起始值,與直接寫區(qū)間(jiān)值效果相同,()為(wèi)不包含區(qū)間(jiān)值。比如[30,40)表示條件左值大(dà)于等于30,同時(shí)小(xiǎo)于40;比如(30,40)表示大(dà)于30,且小(xiǎo)于40。[]和(hé)()符号用在日期區(qū)間(jiān)上(shàng)也能起到同樣的效果 |
不在區(qū)間(jiān)值中 | 與“在區(qū)間(jiān)值中”作(zuò)用相反 |
選擇完比較操作(zuò)符後,我們就可(kě)以來(lái)設置條件右邊部分。條件右邊部分相比左邊,可(kě)選擇的值類型會(huì)更多(duō)一些(xiē),如下圖:
一旦選擇某種類型值之後,我們就可(kě)以進入下一步操作(zuò),同時(shí)在URule Pro當中無論條件左值還(hái)是條件右值都可(kě)以進行(xíng)無限多(duō)級簡單的加、減、乘、除運算(suàn)操作(zuò),如下圖所示:
在配置條件時(shí),需要我們把之前定義好的變量庫文件、參數(shù)庫文件、常量庫文件、動作(zuò)庫文件導入進來(lái)。對于條件來(lái)說,可(kě)以是多(duō)個(gè)條件,也可(kě)以是多(duō)個(gè)複合條件組合,這樣都是通(tōng)過鼠标點擊操作(zuò)完成,這裏就不再贅述。
條件配置完成後,可(kě)以為(wèi)“那(nà)麽”或“否則”部分添加動作(zuò),那(nà)麽部分的動作(zuò)隻有(yǒu)條件滿足時(shí)執行(xíng),反之,否則部分的動作(zuò)隻在條件不滿足時(shí)執行(xíng),不加動作(zuò)意味着什麽也不幹,動作(zuò)可(kě)以有(yǒu)多(duō)個(gè),多(duō)個(gè)動作(zuò)添加完成後可(kě)以通(tōng)過拖曳改變順序。
目前在URule Pro當中支持的動作(zuò)類型有(yǒu)三種,分别是:打印內(nèi)容到控制(zhì)台、變量賦值以及執行(xíng)方法或函數(shù),如下圖所示:
打印內(nèi)容到控制(zhì)台其實就是将我們需要的信息打印輸出到日志(zhì)當中,內(nèi)容可(kě)以是一個(gè)普通(tōng)的輸入值,也可(kě)以是一些(xiē)複雜的值類型或它們的加、減、乘、除組合,及添加括号定義算(suàn)術(shù)運行(xíng)優先級;在規則配置好“允許日志(zhì)輸出”選項時(shí),就可(kě)以看到這個(gè)動作(zuò)對應的輸出內(nèi)容。
變量賦值也就是給當前導入的變量庫或參數(shù)庫的值進行(xíng)賦值,值類型可(kě)以是一個(gè)普通(tōng)的輸入值,也可(kě)以是一些(xiē)複雜的值類型或它們的加、減、乘、除組合,及添加括号定義算(suàn)術(shù)運行(xíng)優先級。
在變量賦值操作(zuò)裏,如果賦值對象的屬性是一個(gè)對象類型,賦值時(shí)可(kě)以直接寫個(gè)JSON為(wèi)這個(gè)對象的部分屬性進行(xíng)賦值。
如Employee對象有(yǒu)個(gè)名為(wèi)company的屬性,該屬性是個(gè)對象類型,對應的Company對象有(yǒu)四個(gè)字段,分别是id,name,address,post,那(nà)麽在進行(xíng)變量賦值操作(zuò)時(shí),如果想一次性為(wèi)這個(gè)company屬性的id,name,post三個(gè)屬性賦值,我們可(kě)以寫下面這樣的JSON值:
{"id":"bstek","name":"銳道(dào)","post":1000815}
将上(shàng)面的JSON值賦給這個(gè)company屬性,JSON中的id,name,post三個(gè)屬性值将會(huì)被寫到company對象中的id,name,post三個(gè)對應子屬性當中。
最後一種類型的動作(zuò)是執行(xíng)方法或函數(shù),要選擇執行(xíng)的方法或函數(shù),前提是我們必須方法所在的動作(zuò)庫文件導入到當前規則文件當中,否則就看不到要執行(xíng)的方法,一旦選擇執行(xíng)方法後,如果當前方法當中包含參數(shù),那(nà)麽我們也需要選擇相應的值為(wèi)參數(shù)賦值,同樣參數(shù)的值可(kě)以是一個(gè)普通(tōng)的輸入值,也可(kě)以是一些(xiē)複雜的值類型或它們的加、減、乘、除組合。動作(zuò)的具體(tǐ)配置都是基于鼠标點擊操作(zuò)的,比較簡單,這裏不再贅述。
在向導式規則編輯器(qì)中,可(kě)以通(tōng)過鼠标拖曳來(lái)改變那(nà)麽或否則部分的動作(zuò)順序,同時(shí),對于多(duō)個(gè)規則文件,也可(kě)以通(tōng)過拖曳來(lái)改變它們的顯示順序。
示例
下面是一個(gè)包含兩個(gè)普通(tōng)規則的決策集文件,導入了我們之前配置的那(nà)個(gè)包含Customer的變量庫文件,在第一個(gè)規則當中條件滿足時(shí)執行(xíng)兩個(gè)動作(zuò),不滿足執行(xíng)一個(gè)動作(zuò);第二個(gè)規則條件滿足的話(huà)執行(xíng)兩個(gè)動作(zuò),不滿足什麽也不做(zuò),如下圖所示:
可(kě)以看到這兩個(gè)規則條件都比較簡單,并且他們是互斥的,同一時(shí)刻最多(duō)隻會(huì)滿足一個(gè)規則。
接下來(lái)需要對這個(gè)決策集進行(xíng)測試,測試方法比較簡單,我們可(kě)以直接點擊當前規則文件工具欄上(shàng)的“測試”按鈕針對當前文件進行(xíng)快速測試, 也可(kě)以點擊項目的“知識包”節點,在打開(kāi)的編輯器(qì)中添加一個(gè)知識包,并将這個(gè)做(zuò)好的規則集文件放到這個(gè)包中進行(xíng)打包測試,如下圖所示:
知識包是URule Pro中提供的一種用于将一個(gè)或多(duō)個(gè)規則集、決策表、交叉決策表、決策樹(shù)、評分卡、複雜評分卡、評分流文件打包的工具,知識包的編碼屬性比較重要,是這個(gè)包在當前項目中的ID。 定義好知識包及這個(gè)包中包含的資源文件後,可(kě)以點擊知識包菜單項中的“快速測試”按鈕對當前知識包進行(xíng)測試,如下圖所示。
快速測試是URule Pro當中提供的一種針對知識包的測試工具,通(tōng)過它可(kě)對定義好的知識包預先進行(xíng)測試。 快速測試中,我們可(kě)以把相關的輸入選擇并添加進來(lái),輸入需要的值,同時(shí)把關注的輸出選擇好,這樣就可(kě)以點擊工具欄上(shàng)的測試按鈕對當前知識包中的規則文件或規則流文件進行(xíng)測試(如果當前知識包中含有(yǒu)規則流, 那(nà)麽點擊測試按鈕時(shí)就會(huì)開(kāi)啓這個(gè)規則流,如果有(yǒu)多(duō)個(gè)規則流,這裏也隻會(huì)觸發一個(gè);如果沒有(yǒu)規則流,那(nà)麽就觸發知識包裏的所有(yǒu)規則文件裏的規則)。
實際上(shàng),如果我們需要對單個(gè)規則文件進行(xíng)快速測試,那(nà)麽可(kě)以直接在相關的規則文件中完成,不需要把規則文件加到知識包中進行(xíng), 方法上(shàng)點擊規則文件工具欄上(shàng)的“快速測試”按鈕即可(kě)彈出針對當前規則文件的快速測試窗口(向導式規則文件、評分卡、決策表、決策流等文件裏都在工具欄裏提供了快速測試的按鈕)。
測試窗口中的“查看規則樹(shù)”按鈕是用來(lái)通(tōng)過圖形化展示當前知識包所對應的規則樹(shù)結構,如上(shàng)面的示例,點示此按鈕看到的規則樹(shù)效果如下:
可(kě)以看到,在這棵樹(shù)中,把規則定義用到的所有(yǒu)條件節點都以樹(shù)節點的形式表現出來(lái),條件之間(jiān)如果是并且關系,那(nà)麽這些(xiē)條件節點在樹(shù)中就以串行(xíng)的形式連接,這樣在實際執行(xíng)時(shí)隻有(yǒu)前一個(gè)節點條件滿足才會(huì)流轉到下一節點;條件之間(jiān)如果是或者關系,可(kě)以看到規則樹(shù)會(huì)通(tōng)過一個(gè)"OR"節點将若幹個(gè)條件節點連接,這樣在實際執行(xíng)時(shí),隻要有(yǒu)一邊連線到達這個(gè)“OR”節點,那(nà)麽與這個(gè)“OR”節點連接的其它連線上(shàng)的條件節點就不再計(jì)算(suàn);如果總的條件使用并且連接,但(dàn)分支上(shàng)有(yǒu)并且和(hé)或者連接的條件,那(nà)麽在構建規則樹(shù)時(shí)就會(huì)将分支上(shàng)的并且條件以串行(xíng)的形式連接,同時(shí)将分支上(shàng)的或者條件使用“OR”節點連接,最後再使用“AND”節點将所有(yǒu)條件連接起來(lái),如上(shàng)圖所示。
如果規則中有(yǒu)兩個(gè)相同的條件,那(nà)麽在構建規則樹(shù)時(shí)會(huì)智能地将這些(xiē)相同節點合并為(wèi)一個(gè)節點,這樣在樹(shù)上(shàng)隻會(huì)顯示一個(gè)節點,通(tōng)過這種相同條件節點的共享機制(zhì)可(kě)以減小(xiǎo)規則樹(shù)尺寸,從而減少(shǎo)內(nèi)存占用。
樹(shù)的最底端,就是具體(tǐ)的規則名。在規則樹(shù)運行(xíng)時(shí),所有(yǒu)的業務對象通(tōng)過頂端名為(wèi)入口的節點插入到規則樹(shù),根據連線評估條件節點是否滿足,如果能到達最底端規則節點, 則說明(míng)與當前規則相關的所有(yǒu)條件滿足,對應規則裏定義的動作(zuò)就進入待執行(xíng)狀态。
利用樹(shù)的特點,再配合相關的短(duǎn)路計(jì)算(suàn)方式,可(kě)以最大(dà)程度上(shàng)保證規則條件計(jì)算(suàn)性能,減少(shǎo)不必要的條件匹配嘗試,從而使得(de)規則的計(jì)算(suàn)性能可(kě)以與普通(tōng)硬編碼相媲美,實現業務計(jì)算(suàn)的毫秒(miǎo)級響應。
循環規則
循環規則,它是一種可(kě)以對集合對象進行(xíng)循環執行(xíng)的規則。
循環規則它的名稱與屬性與普通(tōng)規則一樣,定義循環規則,首先需要定義它的“循環對象”屬性,它要求我們指定一個(gè)集合類型的對象,目前URule Pro提供了兩種類型的集合對象來(lái)源:一種是指定的集合對象, 這個(gè)對象可(kě)以是個(gè)參數(shù)或變量;另一種是指定類型的所有(yǒu)變量對象,選擇這種類型後,當我們選擇某個(gè)變量時(shí),運行(xíng)時(shí)引擎會(huì)自動從當前工作(zuò)區(qū)中找到所有(yǒu)這種類型的變量并組裝成一個(gè)集合返回; 循環規則在運行(xíng)時(shí)會(huì)将這裏選擇的集合對象進行(xíng)叠代。
接下來(lái)定義“開(kāi)始前動作(zuò)”屬性,顧名思義,就是在循環規則執行(xíng)前做(zuò)的一些(xiē)動作(zuò),也可(kě)以理(lǐ)解為(wèi)對集合對象進行(xíng)叠代前要執行(xíng)的動作(zuò);通(tōng)常我們會(huì)在這個(gè)地方做(zuò)一些(xiē)初始化的動作(zuò),比如臨時(shí)參數(shù)的初始化賦值等, 同樣這裏的動作(zuò)可(kě)以是0~n個(gè),如果不定義那(nà)麽就不執行(xíng)。
開(kāi)始前動作(zuò)定義完成後就可(kě)以定義循環規則的循環單元部分,對于一個(gè)循環規則來(lái)說可(kě)以有(yǒu)一個(gè)或多(duō)個(gè)循環單元,每個(gè)循環單元都是一個(gè)普通(tōng)規則的規則體(tǐ),也就是一個(gè)由如果、那(nà)麽、否則三部分構成的普通(tōng),定義方式與普通(tōng)規則完全相同。
在循環規則執行(xíng)時(shí),每叠代一次“循環對象”,就會(huì)将當前叠代的對象插入到工作(zuò)區(qū),嘗試匹配循環單元裏的每一個(gè)規則體(tǐ),如果滿足條件就執行(xíng)。
最後是“結束後動作(zuò)”部分,它在循環執行(xíng)完成後執行(xíng),動作(zuò)可(kě)以是0~n個(gè),不定義就不執行(xíng)。
在決策集設計(jì)器(qì)中,點擊工具欄上(shàng)的“添加循環規則”按鈕就可(kě)以添加一個(gè)循環規則,如下圖所示:
我們來(lái)看一個(gè)例子,通(tōng)過這個(gè)例子來(lái)學習循環規則的使用方法。
示例
我們要實際的業務是統計(jì)用戶對象裏訂單金額小(xiǎo)于1000的數(shù)量以及訂單金額大(dà)于等于1000的數(shù)量。
首先我們需要在Customer實體(tǐ)類裏添加一個(gè)新的屬性orders,如下代碼所示:
@Label("訂單")
private List<Order> orders;
Order類源碼如下:
package com.bstek.entity;
import com.bstek.urule.model.Label;
/**
* @author Jacky.gao
* @since 2016年9月30日
*/
public class Order {
@Label("名稱")
private String name;
@Label("價格")
private float price;
@Label("數(shù)量")
private int amount;
//省略getter和(hé)setter方法
}
打開(kāi)我們的customer變量庫文件,在"會(huì)員"分類下添加orders變量,同時(shí)将新的Order對象添加到庫中,如下圖:
這樣,“會(huì)員”與“訂單”之間(jiān)就形成了一個(gè)一對多(duō)的關系。接下來(lái)我們需要利用循環規則實現一個(gè)簡單的小(xiǎo)需求,那(nà)就是統計(jì)當前會(huì)員的符合條件的訂單價格的總額, 我們目前定義的兩個(gè)BOM對象中,沒有(yǒu)哪個(gè)屬性可(kě)用于存儲訂單數(shù)量,所以需要添加兩個(gè)臨時(shí)的參數(shù)值,用來(lái)存儲小(xiǎo)于1000的訂單數(shù)和(hé)大(dà)于或等于1000的訂單數(shù),如下圖所示。
庫文件準備好了之後,接下來(lái)我們就可(kě)以來(lái)定義一個(gè)循環規則來(lái)實現統計(jì)總價的需求了,定義好的規則如下:
我們定義的這個(gè)循環規則中,循環對象類型為(wèi)指定的集合對象,這裏指定對會(huì)員對象的訂單屬性進行(xíng)循環; 循環體(tǐ)中有(yǒu)循環單元,分别用于統計(jì)金額小(xiǎo)于1000的訂單數(shù)量和(hé)金額大(dà)于或等于1000的訂單數(shù)量;最後在循環結束後的動作(zuò)裏添加了将兩個(gè)統計(jì)數(shù)量的參數(shù)輸出到控制(zhì)台的動作(zuò)。
要測試這個(gè)循環規則我們可(kě)以在“知識包”節點,添加這個(gè)包含循環規則的決策集文件,然後針對這個(gè)知識包進行(xíng)快速測試;當然也可(kě)以在這個(gè)規則文件裏點工具欄上(shàng)的快速測試按鈕對這個(gè)循環規則進行(xíng)測試, 測試方法是一樣的。
點擊規則文件工具欄上(shàng)的“快速測試”按鈕,添加一個(gè)會(huì)員對象作(zuò)為(wèi)輸入,并選擇其下的訂單屬性,并構造訂單的JSON格式數(shù)據,如下圖所示:
在上(shàng)圖當中,測試時(shí),我們構造的訂單數(shù)據共有(yǒu)三條,以标準的JSON格式呈現, 關于URule Pro測試時(shí)所需要的JSON格式詳細描述,見知識包測試介紹,這裏不再贅述。
點擊“開(kāi)始測試按鈕”,就完成了訂單總計(jì)統計(jì)功能,點擊日志(zhì)輸出鏈接,就可(kě)以看到規則執行(xíng)信息,如下圖所示:
從上(shàng)圖的日志(zhì)結果可(kě)以看出,規則已正确計(jì)算(suàn)出訂單數(shù)量。
在循環規則當中,有(yǒu)些(xiē)時(shí)候我們可(kě)能需要從子對象中找出一個(gè)符合條件的就可(kě)以了,這樣後面的就不需要循環了,針對這種情況, URule裏還(hái)提供了一個(gè)名為(wèi)“跳(tiào)出循環”的方法,我們隻需要在循環規則體(tǐ)的那(nà)麽中添加這個(gè)方法即可(kě),如下圖所示:
在我們這裏的循環規則中,針對用于統計(jì)數(shù)量的兩個(gè)參數(shù),在循環規則開(kāi)始前并沒有(yǒu)對它們進行(xíng)了初始化,這是因為(wèi)在URule Pro當中,對于參數(shù)的值引擎默認會(huì)進行(xíng)初始化,比如Integer類型的參數(shù)它的默認值就是0, 下表中羅列了參數(shù)中會(huì)被引擎初始化的數(shù)據類型的默認值。
數(shù)量類型 | 初始化後的默認值 |
---|---|
Integer | 0 |
Long | 0 |
Double | 0 |
Float | 0 |
Boolean | false |
List | 一個(gè)不含任何元素的ArrayList對象 |
Set | 一個(gè)不含任何元素的HashSet對象 |
Map | 一個(gè)不含任何元素的HashMap對象 |
規則集中提供了規則模版導入功能。在業務規則的編寫過程中,可(kě)能存在一些(xiē)功能類似的普通(tōng)規則或循環規則,比如某些(xiē)規則隻是條件部分有(yǒu)一點變化, 或者動作(zuò)部分不太一樣,其它都是相同的,對于這種類型的我們沒有(yǒu)必要再重新定義一次,隻需要把功能類似的普通(tōng)規則或循環規則保存為(wèi)模版,然後在需要時(shí)将其導入即可(kě)。利用這種特性可(kě)以大(dà)大(dà)提高(gāo)業務規則的定義效率,節省開(kāi)發時(shí)間(jiān)。
在規則集中,每個(gè)普通(tōng)規則和(hé)循環規則名前都有(yǒu)一個(gè)複選框,我們可(kě)以根據需要勾選後點擊工具欄上(shàng)的“保存為(wèi)模版按鈕”,如下圖所示:
在彈出的窗口中輸入模版名稱及相關備注信息後即可(kě),如果當前沒有(yǒu)模版分類可(kě)以先創建一個(gè)分類(模版分類是為(wèi)了更好的管理(lǐ)規則模版),然後選中後即可(kě)保存。
有(yǒu)了規則模版後,接下來(lái)就可(kě)以打開(kāi)需要導入模版的規則集文件,選擇工具欄上(shàng)的“從模版導入”按鈕,就可(kě)以将選擇的規則模版導入到當前規則集文件中。
規則模版的适用範圍是當前項目,也就是說當前項目中定義的模版在當前項目中的任何一個(gè)規則集文件中都可(kě)以導入使用,有(yǒu)了規則模版可(kě)大(dà)幅減少(shǎo)重複勞動,提高(gāo)開(kāi)發效率。
對象名與屬性名的分隔
從2.1.1版本開(kāi)始,在向導式規則中引用變量或常量時(shí),分類名與具體(tǐ)屬性名之間(jiān)的分隔符支持用戶自定義,其中變量默認為(wèi)“的”;常量默認為(wèi)空(kōng)(分隔符為(wèi)空(kōng)時(shí)常量隻顯示常量值而不顯示分類),如下圖所示:
在使用過程中,如果覺得(de)默認提供的分隔方式看起來(lái)不滿足要求,那(nà)麽可(kě)以通(tōng)過修改下面兩個(gè)屬性來(lái)實現對變量以及常量分隔符的自定義功能:
屬性名 | 默認值 | 描述 |
---|---|---|
urule.variable.link | 的 | 用于定義向導式規則中變量分類與屬性之間(jiān)的分隔符 |
urule.constant.link | 空(kōng) | 用于定義向導式規則中常量分類與屬性之間(jiān)的分隔符,因為(wèi)該屬性默認值為(wèi)空(kōng),所以我們看到默認向導式規則中常量不顯示分類,隻顯示值,如果給該屬性定義具體(tǐ)值,那(nà)麽常量的分類就會(huì)顯示出來(lái) |
條件模版
從2.1.9版本開(kāi)始,可(kě)以在“規則集”分類中創建“條件模版”文件,條件模版的作(zuò)用就是把一些(xiē)通(tōng)用條件進行(xíng)歸類,并定義好有(yǒu)意義的名稱,這樣在向導式的規則集文件裏就可(kě)以引用條件模版文件并在規則條件中使用條件模版,一個(gè)創建好的條件模版文件效果如下圖所示:
條件模版創建完成後,就可(kě)以在向導式規則文件裏引用并使用了,引用方式與導入庫文件的方法一緻,點擊工具欄上(shàng)的“模版”按鈕,選擇其下的“條件模版”菜單項,然後選擇并添加相應的條件模版文件即可(kě),如下圖所示:
使用導入的條件模版,隻需要在規則條件裏選擇“添加條件模版”即可(kě),如下圖所示:
從2.1.9版本開(kāi)始,對于向導式規則,在規則名邊,還(hái)添加了一個(gè)可(kě)以用于直接查看當前規則在編譯後條件樹(shù)的按鈕,這對于采用了條件模版的規則來(lái)說非常有(yǒu)意義,通(tōng)過查看編譯後的條件樹(shù),就可(kě)以明(míng)确在添加了條件模版後對當前規則的條件組合産生(shēng)的影(yǐng)響, 從而可(kě)以幫助我們更好的理(lǐ)解規則中配置的條件。
動作(zuò)模版
從2.2.1版本開(kāi)始,向導式規則集中開(kāi)始支持動作(zuò)模版。可(kě)以在“規則集”分類下創建“動作(zuò)模版”文件,在動作(zuò)模版文件中,可(kě)以把一些(xiē)通(tōng)過的動作(zuò)定義出來(lái),并賦予有(yǒu)意義的名稱,這樣在向導式規則集文件中就可(kě)以引用動作(zuò)模版文件并在規則的動作(zuò)部分使用它, 動作(zuò)模版文件如下圖所示:
定義好動作(zuò)模版文件後,就可(kě)以在向導式規則文件裏引用并使用了,引用方式與導入庫文件的方法一緻,點擊工具欄上(shàng)的“模版”按鈕,選擇其下的“動作(zuò)模版”菜單項,然後選擇并添加相應的動作(zuò)模版文件即可(kě);具體(tǐ)使用方法與條件模版相同,這裏就不再贅述。
規則集的運行(xíng)模式
在2.1.7版本以前,向導式規則集在默認模式下會(huì)把當前文件中所有(yǒu)所有(yǒu)規則編譯成一棵規則樹(shù),根據輸入對象先進行(xíng)條件匹配計(jì)算(suàn),計(jì)算(suàn)好後再根據規則設定的優先級來(lái)執行(xíng)所有(yǒu)匹配規則的動作(zuò)部分。
如果存在兩個(gè)規則A、B,A規則的優先級高(gāo)于B,A規則根據輸入默認對象屬性值條件可(kě)以滿足,而B規則根據輸入對象條件不滿足,這時(shí)執行(xíng)A規則動作(zuò)部分,在動作(zuò)中将輸入對象某屬性改為(wèi)另外一個(gè)值,經過這個(gè)修改, B規則此時(shí)條件滿足了,但(dàn)在默認模式下,所有(yǒu)規則的條件匹配動作(zuò)已經完成了,所以在A規則的動作(zuò)部分将輸入對象某屬性改為(wèi)B規則滿足的值後,B規則也不會(huì)嘗試重新匹配條件以執行(xíng)B規則條件滿足後的動作(zuò)部分。
要實現這一功能,在2.1.7之前的版本當中,我們隻能在A規則條件滿足後的修改輸入對象某屬性值的動作(zuò)後添加一個(gè)“更新工作(zuò)區(qū)”的函數(shù),更新這個(gè)修改後的輸入對象,以使這個(gè)對象能重新匹配所有(yǒu)的規則, 看看有(yǒu)沒有(yǒu)滿足條件的,這樣B規則才會(huì)被重新激活;或者使用“執行(xíng)組”屬性也能達到同樣的目的,也就是給B規則添加一個(gè)“執行(xíng)組”屬性,在A規則條件滿足後的修改輸入對象某屬性值的動作(zuò)後加上(shàng)激活B規則對應的執行(xíng)組。
可(kě)以看到,在默認模式下,對于存在大(dà)量相互依賴的向導式規則來(lái)說,上(shàng)述兩種方式用起來(lái)還(hái)是很(hěn)麻煩的,為(wèi)此從2.1.7版本開(kāi)始,對于向導式規則集文件添加了一種新的“順序”運行(xíng)模式, 通(tōng)過向導式規則集的工具欄配置菜單按鈕下的運行(xíng)模式菜單項,即可(kě)實現将默認模式修改為(wèi)“順序模式”,如下圖所示:
在這種模式下,當前規則集裏的所有(yǒu)規則将不會(huì)被編譯成一整棵規則樹(shù),而是每個(gè)規則都會(huì)獨立的編譯成一個(gè)規則樹(shù),運行(xíng)的時(shí)候,會(huì)根據規則定義的優先級屬性依次運行(xíng)這些(xiē)規則樹(shù), 這樣,對于存在上(shàng)述邏輯情況的業務來(lái)說,我們隻需要修改運行(xíng)模式為(wèi)“順序模式”,同時(shí)為(wèi)各個(gè)規則定義好優先級,那(nà)麽它們就會(huì)逐個(gè)執行(xíng),優先級較高(gāo)的規則先執行(xíng), 執行(xíng)後的動作(zuò)部分如果存在對業務數(shù)據的修改,就會(huì)直接影(yǐng)響到後面規則條件的匹配,不再需要使用“更新工作(zuò)區(qū)”以使規則重新嘗試匹配或者使用“執行(xíng)組”屬性對規則執行(xíng)順序進行(xíng)編排,這樣可(kě)以大(dà)大(dà)簡化業務規則定義的複雜度。
需要指出的是“順序模式”下,因為(wèi)規則是一條條匹配,所以性能上(shàng)相比“默認模式”要差一些(xiē),如沒有(yǒu)特殊需要不建議采用“順序模式”。