對于業(yè)務(wù)復(fù)雜多變的項(xiàng)目存在的問題??????
1) 當(dāng)業(yè)務(wù)規(guī)則變更時,對應(yīng)的代碼也得跟著更改,每次即使是小的變更都需要經(jīng)歷開發(fā)、測試驗(yàn)證上線等過程,變更成本比較大。?????
?2) 長時間系統(tǒng)變得越來越難以維護(hù)。?????
?3) 開發(fā)團(tuán)隊(duì)一般是由一個熟悉業(yè)務(wù)的BA(業(yè)務(wù)分析人員)和若干個熟悉技術(shù)的開發(fā)人員組成,開發(fā)人員對業(yè)務(wù)規(guī)則的把握能力遠(yuǎn)不及BA,但實(shí)際上卻承擔(dān)了將業(yè)務(wù)規(guī)則準(zhǔn)確無誤實(shí)現(xiàn)的重任。??????
4) 系統(tǒng)僵化,新需求插入困難。?????
?5) 新需求上線周期較長。
規(guī)則引擎
??????規(guī)則引擎由推理引擎發(fā)展而來,是一種嵌入在應(yīng)用程序中的組件,實(shí)現(xiàn)了將業(yè)務(wù)決策從應(yīng)用程序代碼中分離出來,并使用預(yù)定義的語義模塊編寫業(yè)務(wù)決策。接受數(shù)據(jù)輸入,解釋業(yè)務(wù)規(guī)則,并根據(jù)業(yè)務(wù)規(guī)則做出業(yè)務(wù)決策。
規(guī)則引擎能幫助我們什么
? ? ? 把規(guī)則和核心業(yè)務(wù)拆開,規(guī)則單獨(dú)配置。這樣當(dāng)我們的規(guī)則變化的時候,就可以通過修改規(guī)則文件而不用修改核心的代碼了。
什么樣的項(xiàng)目適合使用規(guī)則引擎
? ? ? 在規(guī)則較為復(fù)雜的行業(yè),都是適用的,如金融、制造、醫(yī)療、物流等行業(yè),面臨的規(guī)則變化較為復(fù)雜,目前使用較多。而且對規(guī)則引擎需求的行業(yè)也將越來越多,如團(tuán)購平臺、傳統(tǒng)企業(yè)管理渠道等。
規(guī)則引擎常用的框架有哪些
JBoss Drools? ? Rete算法
Mandarax
JLisa
OpenRules
JEOPS
InfoSapient
JRuleEngine
Roolie
Rete算法
? ? ? ?Rete 模式匹配算法是在模式匹配中利用推理機(jī)的時間冗余性和規(guī)則結(jié)構(gòu)的相似性, 通過保存中間去處來提高推理效率的一種模式匹配算法。
? ? ? ?在模式匹配過程中, 規(guī)則的前提中可能會有很多相同的模塊, 因此在匹配規(guī)則前提時, 將進(jìn)行大量的重復(fù)運(yùn)算, 這樣就帶來時間冗余性問題。例如:
RULE1:if (A>B) and D or C then E=100
RULE2:if (A>B) and (B<C) then E=200
RULE3:if (!(A>B) or (B<C)) then E=300
若要匹配這3 條規(guī)則時, 對于表達(dá)式A>B 要進(jìn)行三次計(jì)算, 對B<C 需要兩次計(jì)算。Rete 采用的方法為: 令M1=A>B, M2=B<C; 則規(guī)則可改為:
RULE1:if (M1) and D or C then E=100
RULE2:if (M1) and (M2) then E=200
RULE3:if (!(M1) or (M2)) then E=300
? ? ? ? 這樣只有當(dāng)A 或B 發(fā)生變化時, 才重新計(jì)算E1; 同樣當(dāng)B 或C 發(fā)生變化時, 重新計(jì)算E2。這樣的推理避免了在每次進(jìn)行模式匹配都重復(fù)計(jì)算相同的表達(dá)式, 而只要檢測相關(guān)參數(shù)是否變化來決定是否更新表達(dá)式, 這樣在推理過程中節(jié)省了大量時間和開銷, 從而提高了推理效率。
? ? ? ? Rete算法通過保存操作過程中的狀態(tài),避免了大量的重復(fù)計(jì)算。Rete算法主要是為那些事實(shí)集合變化不大的系統(tǒng)設(shè)計(jì)的,當(dāng)每次事實(shí)集合的變化非常劇烈時,Rete的狀態(tài)保存算法效果并不理想。?
Groovy實(shí)現(xiàn)輕量級規(guī)則引擎
? ? ? ?Drools是一個高性能的規(guī)則引擎,但是設(shè)計(jì)的使用場景和在本次測試中的場景并不太一樣,Drools的目標(biāo)解決如何快速匹配復(fù)雜對象(如有上百上千的屬性),而不是簡單對象重復(fù)匹配規(guī)則。
? ? ? ?Groovy是動態(tài)語言,依靠反射方式動態(tài)執(zhí)行表達(dá)式的求值,并且依靠JIT編譯器,在執(zhí)行次數(shù)夠多以后,編譯成本地字節(jié)碼,因此性能非常的高,適應(yīng)于反復(fù)執(zhí)行的表達(dá)式,用Groovy腳本動態(tài)調(diào)整線上代碼,無須發(fā)版。
Groovy動態(tài)原理
? ? ? ? Groovy編譯器先將.groovy文件編譯成.class文件,然后調(diào)用JVM執(zhí)行*.class文件,可以在Java項(xiàng)目中集成Groovy并充分利用Groovy的動態(tài)功能;
? ? ? ? Groovy兼容幾乎所有的java語法,開發(fā)者完全可以將groovy當(dāng)做Java來開發(fā),甚至可以不使用Groovy的特有語法,僅僅通過引入Groovy并使用它的動態(tài)能力;
? ? ? ? Groovy可以直接調(diào)用項(xiàng)目中現(xiàn)有的Java類(通過import導(dǎo)入),通過構(gòu)造函數(shù)構(gòu)造對象并直接調(diào)用其方法并返回結(jié)果。
? ? ? ?我們知道在Java中,使用反射可以在運(yùn)行時探索程序的結(jié)構(gòu),以及程序的類和類的方法,然而我們還是無法在運(yùn)行時去修改一個對象的類型或是為對象或類動態(tài)的添加方法,甚至在運(yùn)行時去動態(tài)的生成一個類。但是基于Groovy的元編程,我們可以很輕松的為類動態(tài)的添加方法等。
? ? ? ?MetaClass就是我們所說的元,通過操作MetaClass,就可以動態(tài)的在運(yùn)行時去改變類中的屬性和方法。正是因?yàn)槲覀兯械念惗加幸粋€MetaClass屬性,所以我們的元編程并不會去修改我們的真正定義的類,而實(shí)際是去動態(tài)的操作MetaClass中的內(nèi)容。
? ? ? ?在MetaClassRegister類中有一個Map,在這個Map中會為所有的Java類去存一個對應(yīng)的MetaClass,而所有的Groovy類中已經(jīng)有這個屬性了,所以不必單獨(dú)去保存。
參考文檔:
drools:https://blog.csdn.net/kisscatforever/article/details/80784675
? ? ? ? ? ? ??https://blog.csdn.net/tiandixuanwuliang/article/details/90675869
kie workbench:https://blog.csdn.net/liao0801_123/article/details/89497854
Rete算法:https://nanjingjiangbiao-t.iteye.com/blog/1793563
? ? ? ? ? ? ? ? ? ?http://www.itdecent.cn/p/3e9afe9e0617
Groovy:https://blog.csdn.net/haigenwong/article/details/22947173
? ? ? ? ? ? ? ??https://www.imooc.com/article/44628?block_id=tuijian_wz
? ? ? ? ? ? ? ??http://www.itdecent.cn/p/c7803626c09d