上次提到用服務層的概念整合業務流程與功能性交易,並指出因應交易流程整合的非同步呼叫考量的兩種技術實作方式,也就是 database sharing 與 message queue 的不同做法。兩種做法會殊途同歸,最後會依據處理狀態,呼叫後端的服務進行後續系統作業。
既然兩種做法會殊途同歸,那麼在設計上,可不可以設計出同時適用不同實作方法的非同步機制呢?依據這樣的設計思路,我們會希望把會變動的部分用界面封裝起來,如下圖所示。
在上圖的設計中,我們定義了一個 ServiceEvent,用以記錄交易識別碼、交易階段代碼及流程代碼等資訊,其中流程代碼的目的可提供系統進行更精細的控制,而交易識別碼及交易階段代碼則是用以取得交易目前處理狀態以讓系統繼續處理交易的後續動作。
ServiceEvent 由 EventAdvice 產生,並由 EventListener 讀取,而傳送及接收 ServiceEvent 的任務則交由實作 EventSender 及 EventReader 的類別來處理,如此便可達到不會因為不同的實作方式而更動到設計。
當 EventListener 成功讀取 ServiceEvent 後,則委託 ServiceActivator 來呼叫後續服務。而為了避免實作 ServiceActivator 的類別與後端服務的相互耦和,我們設計了 MappingActivator 並聚合多個 ServiceAction 來解耦,即依據交易的交易階段代碼、流程代碼等資訊,透過 ServiceAction 的實作呼叫後端服務,而開發者只要在設定檔中記錄其映對資訊,而不須寫死在 ServiceActivator 的實作當中。
因此,功能性交易只要在其交易確認後,透過 EventAdvice 通知系統啟動長時間交易的後續功能性交易,就可以達到交易流程的整合。然而,這樣做其實有點美中不足,每個功能性交易的服務都必須額外呼叫 EventAdvice,這在業務領域邏輯上似乎有點不自然,雖然它是必要之系統級服務,但兩者如果可以在關切點上做個分離,這樣實做服務的人員就可以不須理會系統面的問題了。
這樣的設計考量可利用 AOP 的設計概念來予以支持。將服務傳訊的系統服務加入至業務服務的横切面中,便可輕易地達成關切點分離的設計目標,實作服務的開發者不須理會服務傳訊的問題,取而代之的是在配置過程中將服務傳訊的觀點織入所有業務服務中,而形成將整體織入部分的全像圖組織的複雜性系統有機體。
業務服務其實本身是個界面,其實作可專注於業務領域上,而系統級服務也藉由加入點以結合不同層面的觀點,如日誌、交易管理、異常處理、以及此處所提到的服務傳訊等。EventAdvice 在此處是名符其實的因應傳訊服務觀點所實作的裝置,一個當業務服務呼叫完成後會自動呼叫的裝置。
所以,善用設計上的巧思,我們會讓流程與交易的整合變得單純而簡單。當然,實作上還有一些小細節限於篇幅無法在此詳述,例如 EventAdvice 如何針對不同業務服務操作的簽章產生正確的 ServiceEvent、將 ServiceAction 元件化的實作議題,但這些都不是相當複雜的問題:前者可應用 abstract factory pattern 解決物件生成的問題,後者可運用複合物件的方式設計流程控制元件。設計的重點還是在把會變動的地方封裝起來,所謂「通其變,使民不倦;神而化之,使民宜之」,這也正是易窮則變,變則通,通則久的真理呀。
Powered by ScribeFire.