天天看點

軟體設計之業務邏輯層設計

業務邏輯層(Business Logic Layer)無疑是系統架構中展現核心價值的部分。它的關注點主要集中在業務規則的制定、業務流程的實作等與業務需求有關的系統設計,也即是說它是與系統所應對的領域(Domain)邏輯有關,很多時候,我們也将業務邏輯層稱為領域層。例如Martin Fowler在《Patterns of Enterprise Application Architecture》一書中,将整個架構分為三個主要的層:表示層、領域層和資料源層。作為領域驅動設計的先驅Eric Evans,對業務邏輯層作了更細緻地劃分,細分為應用層與領域層,通過分層進一步将領域邏輯與領域邏輯的解決方案分離。

業務邏輯層在體系架構中的位置很關鍵,它處于資料通路層與表示層中間,起到了資料交換中承上啟下的作用。由于層是一種弱耦合結構,層與層之間的依賴是向下的,底層對于上層而言是“無知”的,改變上層的設計對于其調用的底層而言沒有任何影響。如果在分層設計時,遵循了面向接口設計的思想,那麼這種向下的依賴也應該是一種弱依賴關系。因而在不改變接口定義的前提下,理想的分層式架構,應該是一個支援可抽取、可替換的“抽屜”式架構。正因為如此,業務邏輯層的設計對于一個支援可擴充的架構尤為關鍵,因為它扮演了兩個不同的角色。對于資料通路層而言,它是調用者;對于表示層而言,它卻是被調用者。依賴與被依賴的關系都糾結在業務邏輯層上,如何實作依賴關系的解耦,則是除了實作業務邏輯之外留給設計師的任務。

與領域專家合作

設計業務邏輯層最大的障礙不在于技術,而在于對領域業務的分析與了解。很難想象一個不熟悉該領域業務規則和流程的架構設計師能夠設計出合乎客戶需求的系統架構。幾乎可以下定結論的是,業務邏輯層的設計過程必須有領域專家的參與。在我曾經參與開發的項目中,所涉及的領域就涵蓋了電力、半導體、汽車等諸多行業,如果缺乏這些領域的專家,軟體架構的設計尤其是業務邏輯層的設計就無從談起。這個結論唯一的例外是,架構設計師同時又是該領域的專家。然而,正所謂“千軍易得,一将難求”,我們很難尋覓到這樣卓越出衆的人才。

領域專家在團隊中扮演的角色通常稱為Business Consultor(業務咨詢師),負責提供與領域業務有關的咨詢,與架構師一起參與架構與資料庫的設計,撰寫需求文檔和設計用例(或者使用者故事User Story)。如果在測試階段,還應該包括撰寫測試用例。理想的狀态是,領域專家應該參與到整個項目的開發過程中,而不僅僅是需求階段。

領域專家可以是專門聘請的對該領域具有較深造詣的咨詢師,也可以是作為需求提供方的客戶。在極限程式設計(Extreme Programming)中,就将客戶作為領域專家引入到整個開發團隊中。它強調了現場客戶原則。現場客戶需要參與到計劃遊戲、開發疊代、編碼測試等項目開發的各個階段。由于領域專家與設計師以及開發人員組成了一個團隊,貫穿開發過程的始終,就可以避免需求了解錯誤的情況出現。即使項目的開發與實際需求不符,也可以在項目早期及時修正,進而避免了項目不必要的延期,加強了對項目過程和成本的控制。正如Steve McConnell在建構活動的前期準備中提及的一個原則:發現錯誤的時間要盡可能接近引入該錯誤的時間。需求的缺陷在系統中潛伏的時間越長,代價就越昂貴。如果在項目開發中能夠與領域專家充分的合作,就可以最大效果地規避這樣一種惡性的鍊式反應。

傳統的軟體開發模型同樣重視與領域專家的合作,但這種合作主要集中在需求分析階段。例如瀑布模型,就非常強調早期計劃與需求調研。然而這種未雨綢缪的早期計劃方式,對架構師與需求調研人員的技能要求非常高,它強調需求文檔的精确性,一旦分析出現偏差,或者需求發生變更,當項目開發進入設計階段後,由于缺乏與領域專家溝通與合作的機制,開發人員估量不到這些錯誤與誤差,因而難以及時作出修正。一旦這些問題像毒瘤一般在系統中蔓延開來,逐漸暴露在開發人員面前時,已經成了一座難以逾越的高山。我們需要消耗更多的人力物力,才能夠修正這些錯誤,進而導緻開發成本成數量級的增加,甚至于導緻項目延期。當然還有一個好的選擇,就是放棄整個項目。這樣的例子不勝枚舉,事實上,項目開發的“滑鐵盧”,究其原因,大部分都是因為業務邏輯分析上出現了問題。

疊代式模型較之瀑布模型有很大地改進,因為它允許變更、優化系統需求,整個疊代過程實際上就是與領域專家的合作過程,通過向客戶示範疊代所産生的系統功能,進而及時擷取回報,并逐一解決疊代示範中出現的問題,保證系統向着合乎客戶需求的方向演化。因而,疊代式模型往往能夠解決早期計劃不足的問題,它允許在發現缺陷的時候,在需求變更的時候重新設計、重新編碼并重新測試。

無論采用何種開發模型,與領域專家的合作都将成為項目成敗與否的關鍵。這基于一個軟體開發的普遍真理,那就是世界上沒有不變的需求。一句經典名言是:“沒有不變的需求,世上的軟體都改動過3次以上,唯一一個隻改動過兩次的軟體的擁有者已經死了,死在去修改需求的路上。”一語道盡了軟體開發的殘酷與艱辛!

那麼應該如何加強與領域專家的合作呢?James Carey和Brent Carlson根據他們在參與的IBM SanFrancisco項目中獲得的經驗,提出了Innocent Questions模式,其意義即“改進領域專家和技術專家的溝通品質”。在一個項目團隊中,如果我們沒有一位既能擔任首席架構師,同時又是領域專家的人選,那麼加強領域專家與技術專家的合作就顯得尤為重要了。畢竟,作為一個領域專家而言,可能并不熟悉軟體設計方法學,也不具備面向對象開發和架構設計的能力,同樣,大部分技術專家很有可能對該項目所涉及的業務領域僅停留在一知半解的地步。如果領域專家與技術專家不能有效溝通,則整個項目的前途就岌岌可危了。

Innocent Questions模式提出的解決方案包括:

(1)選用可以與人和諧相處的人員組建開發團隊;

(2)清楚地定義角色和職權;

(3)明确定義需要的互動點;

(4)保持團隊緊密;

(5)雇傭優秀的人。

事實上,這已經從技術的角度上升到對團隊的管理層次了。就好比籃球運動一樣,即使你的球隊集合了五名世界上最頂尖最有天賦的球員,如果各自為戰,要想取得比賽的勝利依舊是非常困難的。團隊精神與權責分明才是取得勝利的保障,軟體開發同樣如此。

與領域專家合作的基礎是保證開發團隊中永遠保留至少一名領域專家。他可以是系統的客戶,第三方公司的咨詢師,最理想是自己公司雇傭的專家。如果項目中缺乏這樣的一個人,那麼我的建議是去雇傭他,如果你不想看到項目遭遇“西伯利亞寒流”的話。

确定領域專家的角色任務與職責。必須要讓團隊中的每一個人明确領域專家在整個團隊中究竟扮演什麼樣的角色,他的職責是什麼。一個合格的領域專家必須對業務領域有足夠深入的了解,他應該是一個能夠俯瞰整個系統需求、總攬全局的人物。在項目開發過程中,将由他負責業務規則和流程的制定,負責與客戶的溝通,需求的調研與讨論,并于設計師一起參與系統架構的設計。編檔是領域專家必須參與的工作,無論是需求文檔還是設計文檔,以及用例的編寫,領域專家或者提出意見,或者作為撰寫的作者,至少他也應該是評審委員會的重要成員。

規範業務領域的術語和技術術語。領域專家和技術專家必須在保證不産生二義性的語義環境下進行溝通與交流。如果出現了解上的分歧,我們必須及時解決,通過讨論确立術語标準。很難想象兩個語言不通的人能夠互相合作愉快,解決的辦法是加入一位翻譯人員。在領域專家與技術專家之間搭建一座語義上的橋梁,使其能夠互相了解、互相認同。還有一個辦法是在團隊内部開展教育訓練活動。尤其對于開發人員而言,或多或少地了解一些業務領域知識,對于項目的開發有很大的幫助。在我參與過的半導體領域的項目開發,團隊就專門邀請了半導體行業的專家就生産過程的業務邏輯進行了全方位的介紹與教育訓練。正所謂“磨刀不誤砍柴工”,雖然我們消費了教育訓練的時間,但對于掌握了業務規則與流程的開發人員,卻能夠提升項目開發進度,總體上節約了開發成本。

加強與客戶的溝通。客戶同時也可以作為團隊的領域專家,極限程式設計的現場客戶原則是最好的示例。但現實并不都如此的完美,在無法要求客戶成為開發團隊中的固定一員時,聘請或者安排一個專門的領域專家,加強與客戶的溝通,就顯得尤為重要。項目可以通過領域專家獲得客戶的及時回報。而通過領域專家去了解變更了的需求,會在最大程度上減少需求誤差的可能。

業務邏輯層的模式應用

Martin Fowler在《企業應用架構模式》一書中對領域層(即業務邏輯層)的架構模式作了整體概括,他将業務邏輯設計分為三種主要的模式:Transaction Script、Domain Model和Table Module。

Transaction Script模式将業務邏輯看作是一個個過程,是比較典型的面向過程開發模式。應用Transaction Script模式可以不需要資料通路層,而是利用SQL語句直接通路資料庫。為了有效地管理SQL語句,可以将與資料庫通路有關的行為放到一個專門的Gateway類中。應用Transaction Script模式不需要太多面向對象知識,簡單直接的特性是該模式全部價值之所在。因而,在許多業務邏輯相對簡單的項目中,應用Transaction Script模式較多。

Domain Model模式是典型的面向對象設計思想的展現。它充分考慮了業務邏輯的複雜多變,引入了Strategy模式等設計模式思想,并通過建立領域對象以及抽象接口,實作模式的可擴充性,并利用面向對象思想與身俱來的特性,如繼承、封裝與多态,用于處理複雜多變的業務邏輯。唯一制約該模式應用的是對象與關系資料庫的映射。我們可以引入ORM工具,或者利用Data Mapper模式來完成關系向對象的映射。

與Domain Model模式相似的是Table Module模式,它同樣具有面向對象設計的思想,唯一不同的是它獲得的對象并非是單純的領域對象,而是DataSet對象。如果為關系資料表與對象建立一個簡單的映射關系,那麼Domain Model模式就是為資料表中的每一條記錄建立一個領域對象,而Table Module模式則是将整個資料表看作是一個完整的對象。雖然利用DataSet對象會丢失面向對象的基本特性,但它在為表示層提供資料源支援方面卻有着得天獨厚的優勢。尤其是在.Net平台下,ADO.NET與Web控件都為Table Module模式提供了生長的肥沃土壤。

轉載于:https://www.cnblogs.com/jes_shaw/archive/2011/02/28/1967505.html