最近結(jié)束了一個(gè)企業(yè)OA系統(tǒng)的項(xiàng)目,客戶是一家海洋航運(yùn)行業(yè)的企業(yè),散運(yùn)業(yè)務(wù)全球第一。該系統(tǒng)以工作流系統(tǒng)為基礎(chǔ)平臺,對員工工作進(jìn)行電子化和規(guī)范化,由系統(tǒng)來驅(qū)動員工自動、快捷、可管地完成日常工作。在開發(fā)過程中,在綜合評比多種工作流產(chǎn)品之后,我們選擇了開源工作流產(chǎn)品——OSworkflow作為底層工作流引擎支撐,通過擴(kuò)展OSworkflow的接口把業(yè)務(wù)系統(tǒng)和工作流引擎完美無縫地集成在一起。本文就是跟大家一起分享osworkflow擴(kuò)展過程中的經(jīng)驗(yàn)心得,希望能對其他朋友有幫助。
在我們開發(fā)團(tuán)隊(duì)介入系統(tǒng)開發(fā)過程之前,這個(gè)項(xiàng)目已經(jīng)完成了 quickstart 階段,留給我們的階段產(chǎn)品有:系統(tǒng)實(shí)現(xiàn)的proposal、一個(gè)能體現(xiàn)用戶page flow的lo-fi,以及在mingle上的 story list和iteration原始計(jì)劃。當(dāng)然,還有項(xiàng)目團(tuán)隊(duì)跟客戶形成的一個(gè)良好的互信基礎(chǔ)和溝通渠道。于是,左 proposal,右 lo-fi,客戶溝通在中間,我們就開始了系統(tǒng)設(shè)計(jì)的 inception。inception階段的目標(biāo)根據(jù)不同項(xiàng)目會有不同。在這個(gè)系統(tǒng)里面,我們完成的目標(biāo)有:確定系統(tǒng)實(shí)現(xiàn)使用的技術(shù)、針對技術(shù)進(jìn)行spike探討可行性、結(jié)合master story以及比較粗略的story list實(shí)現(xiàn)一個(gè)系統(tǒng)prototype。好,工作開始了!
為什么選擇OSworkflow?
工作流系統(tǒng)其實(shí)在理論界已經(jīng)是研究得非常成熟了,有 WfMC 組織來規(guī)范工作流定義語言,而且各種工作流引擎,不僅商業(yè)產(chǎn)品,像 JBPM、OSworkflow、ofbiz等開源產(chǎn)品也都很多。這些產(chǎn)品都各有特點(diǎn),應(yīng)該如何選擇呢?從使用率和文檔完整度來看,JBPM 和 OSworkflow 占了上風(fēng),我們就從這兩者里面選了。JBPM基于UML的狀態(tài)圖和活動圖來定義流程,已經(jīng)加入JBOSS大家庭,但是相對比較重。osworkflow是個(gè)非常輕量級的工作流產(chǎn)品,但是自從2006年就停止活動了。不管如何,選擇的技術(shù)都是要為解決未來系統(tǒng)開發(fā)會面臨的問題,才算是一個(gè)好的可行的選擇。
通過分析quickstart階段的proposal和lo-fi prototype,然后再反復(fù)跟客戶確認(rèn),我們知道了客戶在現(xiàn)階段對系統(tǒng)的要求是:
-
只需要處理線性的工作流(未來可能需要增加對分支/合并的支持)
-
不需要功能復(fù)雜強(qiáng)大的工作流編輯器
-
節(jié)點(diǎn)流轉(zhuǎn)主要是手工觸發(fā),不需要基于規(guī)則
-
需要能和遺留系統(tǒng)已有的工作流定義集成,而已有工作流定義用 osworkflow 定義
根據(jù)客戶對系統(tǒng)的要求,我們選擇了osworkflow作為最終的候選工作流引擎。因?yàn)槲覀儗@幾種工作流產(chǎn)品都不是很熟,對它們是否能滿足系統(tǒng)要求答案不確定。而從另外一個(gè)方面來講,如果系統(tǒng)足夠簡單,我們也可以自己實(shí)現(xiàn)一個(gè)狀態(tài)機(jī),自己實(shí)現(xiàn)對流程節(jié)點(diǎn)流轉(zhuǎn)的維護(hù)。
為了做出選擇,我們又分頭對 osworkflow 的配置文件以及技術(shù)架構(gòu)都進(jìn)行了細(xì)致的研究。研究過程和結(jié)果就不細(xì)說了,網(wǎng)上有很多 OSworkflow 的介紹文章,大家可以參照。OSworkflow 會把一個(gè)簡單的xml配置文件,轉(zhuǎn)換成它定義的流程描述類(XXXDescriptor,我們也把它們稱為osworkflow的models),然后在流轉(zhuǎn)的過程中,將其轉(zhuǎn)換成工作流實(shí)例和工作流節(jié)點(diǎn),并通過相應(yīng)的持久化接口持久化工作流的狀態(tài)。整個(gè)過程用一個(gè)簡圖來表示,就會是:

圖1 OSworkflow model
考慮到 OSworkflow 的實(shí)現(xiàn)也是非常輕量級,并且結(jié)構(gòu)非常清晰,而且為了提供以后對分支/合并、以及自定義規(guī)則等流轉(zhuǎn)形式的支持,我們還是選擇了 OSworkflow,而不是自己去實(shí)現(xiàn)一個(gè)基于狀態(tài)機(jī)的工作流引擎。但是,我們還不能直接把 OSworkflow 放進(jìn)項(xiàng)目里面,然后直接引用:一方面我們不想讓開發(fā)團(tuán)隊(duì)都糾纏于底層 OSworkflow 的技術(shù)細(xì)節(jié),另外一方面也是因?yàn)?OSworkflow 并不能完全滿足客戶的系統(tǒng)要求。我們需要擴(kuò)展!
為什么去擴(kuò)展?
依然是問答模式,OSworkflow 有哪些方面不能滿足我們系統(tǒng)的要求?
1. 系統(tǒng)對各個(gè)流程的定義都能有版本跟蹤
客戶會對流程定義進(jìn)行修改,但是流程修改的過程中,流程應(yīng)該繼續(xù)按照原來的定義進(jìn)行流轉(zhuǎn)。這樣,對于同一份流程,系統(tǒng)會同時(shí)存在兩個(gè)不同的定義,并且都能正常流轉(zhuǎn)。OSworkflow 基于XML文件的流程配置方式在這種情況下就不能滿足。
2. 系統(tǒng)對流程定義的修改能實(shí)現(xiàn)“hot deploy”
客戶對流程定義進(jìn)行修改后,系統(tǒng)能自動提供給用戶新的流程定義,而不需要重啟服務(wù)器。因?yàn)?OSworkflow 是在系統(tǒng)啟動的時(shí)候,將所有的流程定義都載入內(nèi)存,在系統(tǒng)運(yùn)行期不會去檢測流程定義的修改。這樣,OSworkflow 也不能滿足。
3. 相對于系統(tǒng)的要求,OSworkflow 提供的功能還是太復(fù)雜了
因?yàn)?OSworkflow 是提供一個(gè)通用的工作流引擎,所以考慮了很多復(fù)雜的情況。這些復(fù)雜性對我們系統(tǒng)來講,都是額外的不能對客戶產(chǎn)生價(jià)值的特性,而且那些復(fù)雜性的存在,也會讓我們開發(fā)的時(shí)候必須考慮到那些方面,從而影響我們的模型設(shè)計(jì)和開發(fā)。
除了上文提到的幾個(gè)原因,我們考慮的因素還有很多方面,最終我們決定是在OSworkflow基礎(chǔ)上進(jìn)行擴(kuò)展,來滿足我們的要求。
如何進(jìn)行擴(kuò)展?
如何進(jìn)行擴(kuò)展?我們的原則是什么?沒有一個(gè)清晰的目標(biāo),很可能最終擴(kuò)展的方向和最終實(shí)現(xiàn)就會跟我們想要的目標(biāo)離得比較遠(yuǎn)了。
原則一. DDD,MDA
我們希望開發(fā)團(tuán)隊(duì)在設(shè)計(jì)開發(fā)的過程中只需要考慮系統(tǒng)領(lǐng)域的模型,而不會 involve 到底層的流程流轉(zhuǎn)細(xì)節(jié)。
“find core domain models”,我們重新研究了系統(tǒng)的 proposal 和 lo-fi prototype,找出系統(tǒng)里面的領(lǐng)域?qū)ο螅鼈冎g存在這樣的一個(gè)關(guān)系:

圖2 系統(tǒng)model
從圖1 OSworkflow model 關(guān)系圖和圖2 系統(tǒng) model 關(guān)系圖可以看出,它們兩者還是存在著一定的相似點(diǎn)和不同點(diǎn)的。
相同點(diǎn):
1. 相應(yīng) model 完成的功能和職責(zé)是非常類似的
2. 不同 model 之見的關(guān)系也是非常類似的
不同點(diǎn):
1. model 的屬性
2. model 的一些行為
原則二. decoupling
我們希望項(xiàng)目實(shí)現(xiàn)不依賴于某個(gè)工作流產(chǎn)品,而是可以很方便地遷移到其他的工作流產(chǎn)品。第一想法就是——“laying, isolate by interface”。
其實(shí)工作流產(chǎn)品除了工作流引擎負(fù)責(zé)流程節(jié)點(diǎn)流轉(zhuǎn)之外,都另外包括這三部分:流程定義、定義解析和狀態(tài)持久化。而成熟的工作流產(chǎn)品,不管是JBPM,還是OSworkflow,都會提供接口進(jìn)行隔離。在OSworkflow里面,接口WorkflowFactory會負(fù)責(zé)流程定義的解析和OSworkflow models的初始化,接口WorkflowStore則負(fù)責(zé)將Workflow和WorkflowEntry的狀態(tài)持久化。這樣,我們就可以定制實(shí)現(xiàn)接口,將domain models轉(zhuǎn)換成 OSworkflow models,在流程流轉(zhuǎn)需要持久化流程狀態(tài)的時(shí)候,則會去持久化domain models。
經(jīng)過這樣幾個(gè)方面的論證和分析,得到的最終方案如下:
-
使用domain model,而不是工作流model
-
擴(kuò)展接口將 domain model 轉(zhuǎn)換成工作流 model
-
擴(kuò)展接口提供自定義的工作流狀態(tài)持久化
-
不改動 osworkflow 內(nèi)核
最終實(shí)現(xiàn)

圖3 系統(tǒng)實(shí)現(xiàn)圖
我們得到了什么
- 使用 domain model 進(jìn)行開發(fā)
- 底層工作流引擎對開發(fā)團(tuán)隊(duì)透明
-
設(shè)計(jì)、優(yōu)化工作在應(yīng)用層次來進(jìn)行
(本博未來會以同一個(gè)項(xiàng)目為例對敏捷項(xiàng)目各個(gè)階段過程進(jìn)行簡單的介紹,敬請期待)