11.規(guī)則流

2019-10-15 12:11 更新

11.規(guī)則流

簡介

規(guī)則流又稱決策流,它整個的結(jié)構(gòu)類似于工作流,用來對已有的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流的執(zhí)行順序進行編排,以清晰直觀的實現(xiàn)一個大的復(fù)雜的業(yè)務(wù)規(guī)則。

URule Pro規(guī)則引擎中的決策流可以實現(xiàn)對已有的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流進行編排執(zhí)行;編排過程中即可以常見串行執(zhí)行,也可以并行執(zhí)行、或者是根據(jù)條件選擇分支執(zhí)行。URule Pro中提供了一個基于網(wǎng)頁的流程設(shè)計器,通過簡單拖曳就可以快速實現(xiàn)對已有的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流執(zhí)行順序的編排。

URule Pro的規(guī)則流設(shè)計器基于FlowDesigner項目實現(xiàn),該項目在Github上的地址為:https://github.com/jacky6024/flowdesigner,flowdesigner是一款上海銳道自主研發(fā)的在瀏覽器中繪制流程圖的Javascript庫,利用它可以快速開發(fā)出流程圖相關(guān)的設(shè)計器。

一個設(shè)計好的規(guī)則流如下圖所示:

在這個流程設(shè)計器當(dāng)中,上面是工具欄,下面是設(shè)計區(qū),在工具欄第一排可實現(xiàn)流程模版的保存、選擇、創(chuàng)建連接、重做、取消、網(wǎng)格吸附、刪除、豎直居中對齊、水平居中對齊及將多個選中節(jié)點設(shè)置成相同尺寸等工具。

工具欄的第二排就是URule Pro中規(guī)則流支持的流程節(jié)點,URule Pro中規(guī)則流中共有八種類型的節(jié)點,分別是開始節(jié)點、規(guī)則節(jié)點、規(guī)則包節(jié)點、動作節(jié)點、腳本節(jié)點、決策節(jié)點、分支節(jié)點、聚合節(jié)點。

需要注意的是,URule Pro的規(guī)則流中沒有結(jié)束節(jié)點,在URule Pro的規(guī)則流當(dāng)中,規(guī)則流必須要以開始節(jié)點開始,可以在任何分支以任意節(jié)點結(jié)束,這點與類似UFLO 之類的工作流引擎不同,UFLO 之類的工作流引擎要求流必須要以開始節(jié)點開始,同時任何分支都必須要以結(jié)束節(jié)點結(jié)束。

創(chuàng)建決策流

打開URule Pro規(guī)則引擎控制臺,在項目的“決策流”節(jié)點點右鍵,從右鍵菜單中選擇創(chuàng)建決策流,創(chuàng)建一個新的決策流文件,如下圖:

在設(shè)計器的設(shè)計區(qū)中,屬性面板是可移動的,我們可以通過鼠標(biāo)點擊屬性面板任何部位來移動它。點擊工具欄第二行上的流程節(jié)點圖標(biāo),然后在設(shè)計區(qū)單擊,就可以在設(shè)計區(qū)添加對應(yīng)節(jié)點。

在URule Pro的決策流中,節(jié)點圖標(biāo)的尺寸是可以通過鼠標(biāo)改變的;節(jié)點創(chuàng)建完成后,可點擊工具欄第一行上的連線圖標(biāo),在節(jié)點間添加連接。點擊工具欄上的選擇圖標(biāo),可實現(xiàn)節(jié)點或連線的選擇,選擇方式可以是點選,或拖選。

在定義好節(jié)點間的連線后,如需將連線變成折線,那么可以先采用拖選方式選中目標(biāo)連線,如下圖所示:

選中連線后,中連線中間就會出現(xiàn)可拖拽的錨點,拖動描點即可改變連線形狀,如下圖所示:

如不需要這個錨點,那么可以先取消連線的選擇,然后再次選中連線,雙擊要刪除的錨點,這樣即可刪除錨點對象,對應(yīng)的連線也會回到?jīng)]有錨點的狀態(tài)。

節(jié)點或連接選中后就可以在屬性面板上修改它們的屬性,點擊選擇圖標(biāo)后,在設(shè)計區(qū)空白處點擊就可以配置決策流的全局屬性,如定義決策流ID,需要導(dǎo)入的庫文件等。

決策流的全局屬性有兩塊,第一塊就是決策流的ID,這個很重要,在一知識包中,如果有多個決策流,那么決策流ID要唯一;第二部分是導(dǎo)入相關(guān)庫文件,這與之前介紹的決策集、決策表、決策樹、評分卡一樣,唯一不同是這里的庫文件管理放在了屬性面板上。

接下來就來介紹URule Pro中決策流提供的各種類型節(jié)點的作用及使用方法。

開始節(jié)點

開始節(jié)點,是一個規(guī)則流開始的地方,在URule Pro當(dāng)中,決策流必須要以開始節(jié)點開始,開始節(jié)點的屬性比較簡單,只有兩個,如下表所示:

屬性名 數(shù)據(jù)類型 描述
節(jié)點名稱 String 設(shè)置當(dāng)前節(jié)點名稱
事件Bean String 一實現(xiàn)了com.bstek.urule.model.flow.NodeEvent接口配置在Spring中bean的id,一旦配置在流程進入及離開該節(jié)點時會觸發(fā)這個實現(xiàn)類

NodeEvent接口源碼如下:

package com.bstek.urule.model.flow;
import com.bstek.urule.model.flow.ins.FlowContext;
import com.bstek.urule.model.flow.ins.FlowInstance;
/**
 * @author Jacky.gao
 * @since 2015年4月20日
 */
public interface NodeEvent {
    /**
     * 規(guī)則流流入當(dāng)前節(jié)點觸發(fā)的方法
     * @param node 當(dāng)前節(jié)點對象
     * @param instance 當(dāng)前規(guī)則流實例對象
     * @param context 規(guī)則流上下文件對象
     */
    void enter(FlowNode node,FlowInstance instance,FlowContext context);
    /**
     * 規(guī)則流流出當(dāng)前節(jié)點觸發(fā)的方法
     * @param node 當(dāng)前節(jié)點對象
     * @param instance 當(dāng)前規(guī)則流實例對象
     * @param context 規(guī)則流上下文件對象
     */
    void leave(FlowNode node,FlowInstance instance,FlowContext context);
}

開始節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
0 1

規(guī)則節(jié)點

所謂規(guī)則節(jié)點,用來綁定URule Pro當(dāng)中提供的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流文件的節(jié)點。值得注意的是,一個規(guī)則節(jié)點只能與一個當(dāng)前項目中決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流文件綁定,這樣一旦決策流流轉(zhuǎn)到當(dāng)前節(jié)點,那么就可以執(zhí)行與這個規(guī)則節(jié)點綁定的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流文件。

在設(shè)計器中,選中目標(biāo)規(guī)則節(jié)點,就可以在屬性面板中設(shè)置其相關(guān)屬性,規(guī)則節(jié)點屬性如下:

屬性名 數(shù)據(jù)類型 描述
節(jié)點名稱 String 設(shè)置當(dāng)前節(jié)點名稱
事件bean String 一實現(xiàn)了com.bstek.urule.model.flow.NodeEvent接口配置在Spring中bean的id,一旦配置在流程進入及離開該節(jié)點時會觸發(fā)這個實現(xiàn)類
文件 String 與當(dāng)前節(jié)點綁定的決策集、決策表、交叉決策表、決策樹、評分卡、復(fù)雜評分卡或其它決策流文件
版本 String 與當(dāng)前節(jié)點綁定的決策集、決策表、決策樹、評分卡或其它決策流文件的版本

規(guī)則節(jié)點出入連接下如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 0~1

知識包節(jié)點

與規(guī)則節(jié)點不同,知識包節(jié)點是用來與具體的知識包綁定的,這樣就可以實現(xiàn)復(fù)雜規(guī)則調(diào)用。知識包節(jié)點與某個知識包綁定之后,運行時規(guī)則流流轉(zhuǎn)到這個節(jié)點后,就會執(zhí)行與之綁定的知識包,如果綁定的知識包中包含決策流,那么引擎會自動執(zhí)行其中的決策流,如果規(guī)則包中包含的規(guī)則流有多個,那么默認只會執(zhí)行其中的第一個規(guī)則流,否則只執(zhí)行觸發(fā)規(guī)則動作。

知識包節(jié)點屬性如下表所示:

屬性名稱 數(shù)據(jù)類型 描述
節(jié)點名稱 String 設(shè)置當(dāng)前節(jié)點名稱
事件bean String 一實現(xiàn)了com.bstek.urule.model.flow.NodeEvent接口配置在Spring中bean的id,一旦配置在流程進入及離開該節(jié)點時會觸發(fā)這個實現(xiàn)類
知識包 String 要與當(dāng)前節(jié)點綁定的具體的知識包,我們可以通過下拉列表選擇當(dāng)前項目下已創(chuàng)建好的可用知識包。

知識包節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 0~1

動作節(jié)點

動作節(jié)點可以與一個實現(xiàn)了com.bstek.urule.model.flow.FlowAction接口并配置到Spring中的Bean綁定,這樣在運行時,規(guī)則流執(zhí)行到這個動作節(jié)點時就會執(zhí)行與之綁定的FlowAction實現(xiàn)類,動作節(jié)點屬性如下表所示:

屬性名稱 數(shù)據(jù)類型 描述
節(jié)點名稱 String 設(shè)置當(dāng)前節(jié)點名稱
事件bean String 一實現(xiàn)了com.bstek.urule.model.flow.NodeEvent接口配置在Spring中bean的id,一旦配置在流程進入及離開該節(jié)點時會觸發(fā)這個實現(xiàn)類
動作bean String 一個實現(xiàn)了com.bstek.urule.model.flow.FlowAction接口并配置到Spring中的Bean的ID。

FlowAction接口源碼如下所示:

package com.bstek.urule.model.flow;
import com.bstek.urule.model.flow.ins.FlowContext;
import com.bstek.urule.model.flow.ins.FlowInstance;
/**
 * @author Jacky.gao
 * @since 2015年2月28日
 */
public interface FlowAction {
    /**
     * @param node 當(dāng)前節(jié)點對象
     * @param context 規(guī)則流上下文件對象
     * @param instance 當(dāng)前規(guī)則流實例對象
     */
    void execute(ActionNode node,FlowContext context,FlowInstance instance);
}

有了動作節(jié)點,那么在規(guī)則流中就可以執(zhí)行具體的Java類中的方法,因為該Java類是配置在Spring上下文中的,所以類中可訪問Spring環(huán)境所有信息,這樣就可以做一些更為復(fù)雜的業(yè)務(wù)操作。

動作節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 0~1

腳本節(jié)點

顧名思義,腳本節(jié)點就是可以在這個節(jié)點上綁定一段腳本,這樣在運行時,規(guī)則流流轉(zhuǎn)到該節(jié)點時就可以執(zhí)行這段腳本。腳本節(jié)點上的腳本屬性就是我們編寫要執(zhí)行的腳本的地方,如下圖所示:

在腳本屬性中,我們提供了一個腳本編輯器,通過這個編輯器,結(jié)合代碼提示(快捷鍵ALT+/)可快速編寫要執(zhí)行的腳本。腳本節(jié)點中編寫的規(guī)則,完全遵循腳本式?jīng)Q策集中普通規(guī)則的then與end之間動作腳本編寫語法規(guī)范。也就是說,腳本節(jié)點中添加的腳本沒有if、then、end及條件判斷腳本,有的只是執(zhí)行動作的腳本。

在URule Pro中,腳本節(jié)點中直接寫腳本已經(jīng)不再推薦了,所以可以看到類型屬性里有兩個,一個是動作腳本,另一個是向?qū)絼幼?。在動作腳本項里加上了(不推薦)的標(biāo)注,而推薦的做法是選擇向?qū)絼幼鳎x擇向?qū)絼幼骱缶涂梢韵裨谙驅(qū)揭?guī)則集中那樣,通過鼠標(biāo)點擊來完成動作的定義,如下圖所示:

之所以不推薦使用腳本方式來定義動作,和之前在腳本式規(guī)則集里介紹原因一致,那么手寫腳本易出錯,向?qū)Х绞胶唵?,出錯機率低,所以推薦大家使用。在后續(xù)版本中,腳本節(jié)點可能會刪除腳本定義方式,只保留向?qū)絼幼鞫x方式。

腳本節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 0~1

決策節(jié)點

所謂決策節(jié)點就是指在運行時,根據(jù)為其下流出連接配置的條件來決定究竟應(yīng)該走哪條連接的節(jié)點,所以根據(jù)這一特性,決策節(jié)點下流出連接至少要有兩條,否則決策節(jié)點就沒有意義了。

選中決策節(jié)點,在其右邊屬性面板中就可以看到針對決策節(jié)點的配置,如下圖所示:

需要重點介紹的是“決策類型”屬性,決策節(jié)點的有兩種決策類型,分別是"條件"和"百分比"。

當(dāng)選擇決策類型為條件時,就會看到如上圖所示效果。選擇“條件”類型時,在下面出現(xiàn)的在決策項當(dāng)中,可以根據(jù)當(dāng)前決策節(jié)點下流出連接的數(shù)量添加對應(yīng)的決策項,對于每條決策項,都有兩個屬性,分別是"條件腳本"和“流向”,在條件列當(dāng)中,我們可以編寫具體的條件,在流向列中選擇當(dāng)條件列中定義的條件滿足時要流出連線名稱,所以對于決策節(jié)點下流出的連線,我們必須要為其設(shè)置名稱,否則就無法為其定義決策項。

為連線定義名稱,需要首先用拖選的方式選中它,然后就可以在屬性面板上為其定義名稱。

在條件表格中,點擊條件編輯按鈕,就會彈出條件編輯窗口,在這個窗口里,定義條件的方式有兩種:一種是腳本方式;一種是向?qū)Х绞健?/p>

腳本方式定義條件,其語法遵循腳本式規(guī)則中條件部分的語法規(guī)范,同樣因為腳本需要手工編寫的特性,所以現(xiàn)在同樣也不再推薦使用腳本方式定義條件,而是推薦使用向?qū)Х绞蕉x條件,如下圖所示:

如果將決策類型改為“百分比”,則可以看到如下圖所示效果:

如上圖所示,一旦將決策類型改為“百分比”,那么就可以為每個流向設(shè)置流量百分比,如上圖當(dāng)中,在實際規(guī)則流運行時,將有30%走"c1"連線,70%走"c0"連線。配置時無論決策節(jié)點下有多少離開連線,最終所有的百分比加在一起要達到100%, 百分比這里一定要是一個合法的整數(shù),否則會出現(xiàn)錯誤。

百分比模式下還有一個名為“作用范圍”的選項,默認值為“批處理”,表示“百分比”類型的計算有效期為當(dāng)前線程,一旦有新線程開啟,那么這個百分比的值將開始重新計算;如果將“作用范圍”改為“每次調(diào)用”,那么生效就不再局限于當(dāng)前線程,每次調(diào)用在經(jīng)過這個決策節(jié)點時都會根據(jù)百分比進行分流計算。

值得注意的時,當(dāng)選擇決策類型為“條件”,在運行時,當(dāng)決策流流轉(zhuǎn)到當(dāng)前節(jié)點時,如果決策項中定義的各個條件都不滿足,那么規(guī)則流到此就結(jié)束了,相反,如果有多個決策項滿足時,那么系統(tǒng)將取第一條滿足條件的決策項對應(yīng)的流向連線進行向下流轉(zhuǎn),而不會選擇所有滿足條件的連線向下流轉(zhuǎn)。

需要注意的是,百分比類型的“批處理”作用范圍下決策方式,必須要在代碼中通過批處理的方式執(zhí)行才會生效,必須要使用后面章節(jié)里介紹的BatchSession來一次性處理一批數(shù)據(jù),或者一個KnowledgeSession一次性處理一批數(shù)據(jù),否則規(guī)則流永遠都只會走默認的百分比占比最高的那條路徑。
當(dāng)然如果百分比類型的作用范圍改為“每次調(diào)用”,那么規(guī)則的每次調(diào)用都會根據(jù)百分比來計算分流。

決策節(jié)點出入連接線下如下表所示:

流入的連接線 流出的連接線
1~n 1~n

分支節(jié)點

分支節(jié)點是URule Pro當(dāng)中提供的一種可實現(xiàn)規(guī)則流多條并行的節(jié)點,通過這個節(jié)點,可以根據(jù)當(dāng)前節(jié)點下流出連線數(shù)量,將當(dāng)前規(guī)則流實現(xiàn)拆分成若干條子的規(guī)則流實例并行運行,根據(jù)這一特性,分支節(jié)點下至少要有兩條流出的連線才有意義。

在決策流實例流轉(zhuǎn)到分支節(jié)點時,分支節(jié)點會根據(jù)其下流出的連接線數(shù)量將主的實例拆分成與連線對應(yīng)的若干個子實例,以并行方式繼續(xù)運行產(chǎn)生的多個流實例。

分支節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 1~n

默認情況下,分支節(jié)點會將主流程拆分成若干子流程執(zhí)行,在實際執(zhí)行的時候還是在一個線程內(nèi)先后執(zhí)行各個分支。

從2.2.1版本開始,在分支節(jié)點上新增一名為“啟用多線程”的屬性。默認情況下,如果不設(shè)置該屬性,那么它的值為“系統(tǒng)默認”,這時將采用系統(tǒng)中定義的名為urule.flowForkMultiThread參數(shù)的值,由這個參數(shù)值來決定當(dāng)前分支下是否采用多線程運行, urule.flowForkMultiThread參數(shù)值默認為false,也就是不開啟多線程運行。

如果希望其下所有子分支以多線程形式并行,那么可以選中當(dāng)前分支節(jié)點,將其“啟用多線程”屬性設(shè)置為“是”,或者將urule.flowForkMultiThread參數(shù)設(shè)置值為true, 這樣引擎在執(zhí)行到分支節(jié)點時會在不同的線程中執(zhí)行其下各個分支,這對于各個分支業(yè)務(wù)邏輯不相關(guān)的業(yè)務(wù),同時各個分支執(zhí)行比較耗時,通過這樣的配置讓分支在不同線程里執(zhí)行,所以可以明顯提高系統(tǒng)執(zhí)行性能。

需要注意的是分支節(jié)點的“啟用多線程”屬性值為“系統(tǒng)默認”時采用的是名為urule.flowForkMultiThread參數(shù)的值,否則就會覆蓋這個全局參數(shù)的值,由當(dāng)前分支節(jié)點自主決定是否開啟多線程。

注意,當(dāng)設(shè)置了參數(shù)urule.flowForkMultiThread=true 或配置了分支節(jié)點的“啟用多線程”屬性值為“是”時,分支節(jié)點下必須要添加一個聚合節(jié)點,將所有分支連接到聚合節(jié)點上,否則執(zhí)行會出現(xiàn)錯誤。

聚合節(jié)點

聚合節(jié)點就是用來聚合由分支節(jié)點拆分出來的多個子的規(guī)則流的,所以有聚合節(jié)點,就一定要有分支節(jié)點,但有分支節(jié)點卻不一定需要聚合節(jié)點(但如果設(shè)置了參數(shù)urule.flowForkMultiThread=true,或配置了分支節(jié)點的“啟用多線程”屬性值為“是”時,分支節(jié)點就啟用了多線程執(zhí)行功能,這樣分支節(jié)點下一定需要一個聚合節(jié)點,否則會出現(xiàn)錯誤),對于URule Pro的決策流來說,拆分出子的決策流后是否有聚合節(jié)點是可選的,但聚合節(jié)點的出現(xiàn)則一定要有分支節(jié)點來配合,否則聚合節(jié)點就沒有意義了。

聚合節(jié)點出入連接線如下表所示:

流入的連接線數(shù)量 流出的連接線數(shù)量
1~n 0~n

示例

下圖中是一個簡單的決策流定義,它由一個開始節(jié)點、三個腳本節(jié)點和一個決策節(jié)點構(gòu)成。

在這個決策流中,我們定義它的ID為“flow-demo”,同時導(dǎo)入了我們之前定義好的包含“會員”的變量庫文件。決策流在經(jīng)過“開始”節(jié)點后,進入“腳本1”節(jié)點,這個節(jié)點上定義的腳本比較簡單,只是簡單向控制臺輸出一段文本,如下圖:

接下來就進入“決策”節(jié)點,在決策節(jié)點,我們選擇的是“條件”作為決策類型,分別定義了兩條連線的流向條件,如下圖:

流向“to2”連線上定義的條件內(nèi)容如下圖:

流向“to3”連線上定義的條件內(nèi)容如下圖:

從上面的兩張圖中可以看到,當(dāng)會員對象的等級屬性在0~5之間時選擇"to2"連線;在5~10之間時選擇"to3"連線。

決策節(jié)點下面是兩個腳本節(jié)點,為他們定義腳本內(nèi)容如下圖:

決策流定義的信息就是這些,接下來我們在知識包節(jié)點對其進行仿真測試,看看運行路徑是不是如我們所預(yù)期。

打開“知識包”節(jié)點,在其下創(chuàng)建一個新的知識包,將這個決策流文件添加到知識包中,點擊工具欄上的“仿真測試”按鈕,在彈出的窗口中輸入“會員”的等級屬性值,點擊工具欄上的“測試決策流”按鈕,在彈出的窗口中選擇我們定義的“flow-demo”,點擊“操作列”上的測試圖標(biāo),既完成了對當(dāng)前決策流的測試,如下圖:

查看控制臺,可以看到如下圖所示的內(nèi)容輸出:

在上面的例子中,腳本節(jié)點里的動作以及決策節(jié)點中的條件都是采用腳本的方式定義,這里您也可以改成向?qū)Х绞蕉x,比較一下兩種定義方式的區(qū)別,這里就不再贅述。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號