1. 程式人生 > >軟體設計之業務邏輯層設計

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

業務邏輯層(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 模式提供了生長的肥沃土壤。