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

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

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

圖3 系統實現圖
我們得到了什么
- 使用 domain model 進行開發
- 底層工作流引擎對開發團隊透明
-
設計、優化工作在應用層次來進行
(本博未來會以同一個項目為例對敏捷項目各個階段過程進行簡單的介紹,敬請期待)