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