如何做好軟件系統的架構設計
對於外包業務類型的項目,軟件架構設計的目的不同於產品類型的項目。這裏我們主要討論外包業務類型項目的軟件架構設計的目的。1.提供大規模開發的基礎和規範,提供可復用的資產。軟件系統的大規模開發必須有壹定的基礎,遵循壹定的規範,這不僅是軟件工程本身的要求,也是客戶的要求。在架構設計過程中,可以對壹些公共部分進行抽象,形成公共類和工具類,從而達到重用的目的。2.在壹定程度上縮短項目周期,利用軟件架構提供的框架或可復用組件,縮短項目開發周期。3、降低開發和維護的成本,大量的復用和抽象,可以提取壹些開發人員不必關心的通用部分,讓開發人員可以只專註於業務邏輯的實現,從而減少大量的工作量,提高開發效率。4、提高產品質量,好的軟件架構設計是產品質量的保證,尤其是對於客戶經常提出的非功能性需求的滿足。軟件架構設計的原則軟件架構設計必須遵循以下原則:1,滿足功能需求和非功能需求。這是壹個軟件系統最基本的要求,也是架構設計應該遵循的最基本的原則。2.實用原則,就像每壹個軟件系統交付給用戶解決用戶問題時都必須實用壹樣,架構設計也必須實用,否則就是“高來高去”或者“過度設計”。3.滿足復用的要求,最大程度提高開發人員的工作效率。軟件架構設計的幾種觀點我們在討論架構設計應該做什麽的時候,或者在架構設計評審的會議上,經常會問各種各樣的問題,比如開發人員應該如何記錄日誌,如何控制事務。如何才能提高我們開發人員的工作效率,即在單位時間內更好的質量完成更多的功能?如何滿足客戶的非功能性需求?如何讓生產環境中的平臺管理者更好的維護系統?以上問題實際上是軟件系統中不同的涉眾從不同的角度提出來的。要回答這些問題,我們必須從不同的角度來看待軟件架構設計的工作。1.從邏輯架構的角度,站在系統用戶的角度考慮問題,設計的軟件架構能夠滿足業務邏輯的需求,處理日益復雜的業務邏輯需求。2.從開發架構的角度,站在系統開發者的角度考慮問題。設計的架構要易於理解、開發和單元測試,開發人員最好用最少的代碼行完成功能開發。3.從運行架構的角度,考慮到系統運行時的質量要求,尤其是關註系統的非功能性要求,客戶往往要求我們系統的功能屏幕最長響應時間不超過4秒,能夠滿足2000個用戶同時在線使用,系統資源基於角色的安全控制。4.從物理架構的角度,關註系統安裝部署的環境,如IBM HTTP Server+WebSphere Application Server+DB2、WebLogic+Oracle,這些都是最流行的企業應用服務解決方案。5.從數據架構來看,我們今天開發的各種系統,比如MIS、ERP、SAP,基本上都是對各種數據進行操作,把壹堆不是很好理解的數據展現給用戶,自動處理各種數據的操作,所以數據的持久性很重要。1.分析需求,理解業務模型(或領域建模),並選擇關鍵用例。軟件需求可以分為用戶角度和開發者角度,從用戶角度也可以分為功能性需求和非功能性需求。我們必須從不同的角度和層次全面理解和分析需求,理解業務模型。實踐表明,經常被我們忽略的非功能性需求,往往會導致整個項目的失敗。理解業務需求的最佳方式是領域建模。領域建模和需求分析經常交替進行。領域建模主要有以下三個功能:◆探索復雜問題,理清領域知識。馬丁·福勒(Martin Fowler)曾說過,他的面向對象方法最大的優點是有助於解決更復雜的問題。領域建模本身作為壹種輔助思考的工具,幫助我們始終將註意力保持在最重要的業務概念及其關系上,從而能夠持續深入系統地分析和理解需求。領域建模往往是壹個從模糊到清晰,從碎片到系統的過程。◆確定功能範圍,影響擴展性。任何模型都是現實世界中程序的抽象。這種抽象會忽略壹些東西,比如對象的屬性,對象之間的關系,而這些忽略往往是有目的的,決定了函數的範圍。該模型揭示了各種功能背後的結構。如果說定義函數相當於“拍照”,那麽領域建模相當於“做透視”,更關註問題領域的內部結構,相當於把問題領域抽象到壹定程度。好的領域模型不僅能很好地支持現有功能,還能在壹定程度上支持未來可能出現的新需求,體現出良好的可擴展性。◆提供溝通基礎,促進有效溝通。領域建模通常使用UML圖作為表示方式,這為我們的交流提供了方便。當然,有時候文字在描述某些領域的問題時可能更合適、更靈活。在我們公司實際的軟件開發過程中,領域建模往往缺少這個環節,這可能是在以後的工作中需要進壹步完善的地方。雖然我們總是期望架構師能夠完全掌握需求,但是由於時間和精力的限制,擺在我們面前的現實是架構師沒有時間深入分析所有的需求,所以我們的策略是“把好鋼用在刀刃上”,也就是把大部分的時間和精力花在確定架構最重要的關鍵需求上。在選擇關鍵需求時,需要註意的是,高優先級的需求往往是從用戶的角度來看的,可能不是真正的關鍵需求。在《RUP從業者指南》壹書中,它告訴我們如何確定關鍵的功能需求。a .作為應用程序的核心或實現系統主界面的功能b .必須實現的功能,即如果這些功能沒有實現,開發的軟件就失去了價值c .覆蓋了系統架構的某些方面但沒有被其他重要用例覆蓋的功能。2.從不同的角度考慮軟件架構的所有方面。軟件架構設計必須考慮方方面面,根據前期工作建立的領域模型、關鍵需求和系統約束進行設計,從系統用戶、開發人員、系統管理員、部署管理員和數據管理員的角度分析和解決問題。例如,如果我們的運行架構采用集群模式,我們必須小心緩存和會話的使用。如果我們的業務邏輯要求我們操作多個數據庫,我們應該考慮支持兩階段事務提交。只有考慮到所有這些方面,這樣的架構設計才是完整的。至於每個視圖中我們應該設計的細節,其實是關系到整個項目的流程定義的。比如我們有壹個專門的活動安排數據庫概要設計,在架構設計的過程中可以只關註更高層的數據庫特征和數據庫之間的關系,在後續的相關活動中可以設計每個表的數據字典,但是如果沒有這個活動,我們會細化每個表的每個字段和表之間的關系。3.解決技術關鍵問題和困惑在軟件架構設計的過程中,我們經常需要攻克壹些技術關鍵問題和困惑,這是壹項需要紮實的理論知識和豐富的實踐經驗的工作。例如,如何提高整個系統的性能?如何導出極其復雜的“中國式報表”(壹般比西方國家出的報表復雜很多,很多開源的BI框架也不能完全解決問題)?當妳遇到壹個確實很難的問題,可以去百度或者谷歌,咨詢公司的資深技術人員或者專家,或者召開壹個小規模的技術研討會,嘗試通過頭腦風暴的方式尋找答案,從而提高工作效率。4.召開架構設計評審會議,接受同行評審。建築設計評審是極其重要的壹部分。我曾在《七種武器》中形容為離別鉤,因為同事在會上可能會問很多問題或意見,很多意見很尖銳,所以壹定要虛心接受,做好記錄。俗話說,“良藥苦口利於病,忠言逆耳利於行”。在審查會議之前,我們必須完成大量的準備工作。最好準備壹份簡明的電子簡報,列出最重要的問題,這樣在進行評審會議時,就不會漫無目的。我們會在會前把這些材料發給與會者,請他們花時間先了解壹下。在會議進行的時候,要學會控制會議的進度,提高會議的效率。5.在關鍵用例的設計架構上實現功能,以驗證架構。架構設計的驗證也是壹項非常重要的工作,驗證技術有很多。在我們公司,通常使用樣本的形式,即XP中的叠代0和RUP中的切片。這樣做的好處是可以從實際產品的角度有效地驗證架構是否滿足需求,與廢棄的原型驗證技術相比可以節約成本。這個樣本絕不是我們在解決架構設計中的問題時用來做實驗的壹些代碼的拼湊,而是壹個完整的可交付代碼和滿足架構設計的相關文檔以及實現壹個關鍵用例的壹系列規範。同時,這個樣本可以作為妳講解或者訓練架構時的教材,也可以作為開發者使用這個架構進行開發的藍本,甚至只需要簡單的修改就可以復制粘貼。6.交付給客戶進行審查。這個環節可能很多公司都不存在,因為他們的軟件架構不壹定需要客戶審核,但是對於我們這樣的服務公司來說最重要的是客戶的尊重。實施軟件架構設計的活動,就是讓客戶理解並接受妳的架構設計方案,同時客戶也會起到幫助妳驗證架構的作用。通常我們的架構被客戶認可後,就可以進入大規模開發。在交付客戶評審時,評審可能通常以會議的形式進行,所以我們可以參考評審會議中的良好做法並召開會議,這裏就不贅述了。軟件架構設計常見誤區及解決方案1,架構設計往往“高大上”。所謂高到不能再高,其實就是我們的架構設計只停留在模型階段,但絕不是第壹個樣本方案。2.架構設計在某些方面經常被過度設計。為了壹些根本不會發生的變化,進行了壹系列復雜的設計。這樣的設計稱為過度設計,往往會帶來資源的浪費,增加開發的工作量或難度。雖然要考慮系統的擴展性和可維護性,但也不能過度設計。有時候妳可能無法判斷哪些設計是過度設計。這時候妳可以請妳的PM從整個項目的高度來幫妳做決定。3.架構不是壹個框架,也不是幾個框架或者技術的簡單組合。框架本身有壹個架構。框架壹般是針對某個方面或領域的半成品,具有良好的復用性和擴展性。我們可以用壹句經典的話來概括:框架是軟件,架構不是軟件,框架是壹種特殊的軟件。在我們的工作中,我們可以通過抽象許多可重用的工具類、公共類和基本類來形成壹些可重用的框架。4.建築設計絕不是展示新技術的平臺。合適的技術是對項目有益的技術,必須考慮開發人員和維護人員的能力。作為架構師,我們更應該關註如何平衡業務需求、編織操作(主要指團隊合作)和技術之間的關系,而不是只關註那些技術細節。5.架構設計的成功決定了系統的質量。因為糟糕的架構設計,交付的系統bug太多,無法滿足客戶的非功能性需求,項目取消的案例時有發生。建築設計不是建築師壹個人的事,也不是幾天就能完成的。它必須是架構師大量辛勤工作的結果,其成敗往往與組織、主管和項目經理的支持密切相關。關於建築設計的壹些通用技巧:1和層法則。這裏的層是指邏輯層,而不是物理層。目前,大多數企業應用系統分為三層,即表示層、領域層和數據層。在劃分每壹個層次時,主要可以考慮以下幾個方面:a、每壹個層次都是相對獨立的部分,可以作為壹個整體使用,不需要了解其他層次;b、盡量減少層級之間的依賴,即減少耦合;c、某壹層可以有壹定程度的替代,對其他層沒有太大的影響;d、等級制度不能封閉壹切。如果將字段添加到用戶界面,數據字段將被添加到域層,相應的字段將被添加到數據層。同時,層數過多可能會對性能產生壹定的影響。2.包之間沒有循環依賴。通常情況下,會先將包分成不同的邏輯層,然後根據該層的包下的功能。避免房間之間的循環依賴是壹個通用規則,這樣的規則必然有其存在的價值和理由。主要原因有:a、循環依賴會使分層失去意義;b、循環依賴會帶來很多潛在的風險,比如嵌套事務的現象(JavaEE標準不支持)。我遇到過這樣的問題。在項目中,事務被放在業務邏輯層進行統壹控制。但是由於開發者在架構上忽略了這個原則,在持久層中調用了表示層的公共類,導致了嵌套事務的現象。3.設計模式的應用。在很多人心目中,提供設計模式等同於GOF的設計模式。其實設計模式是壹個廣義的概念,比如需求模式、領域模式、反模式等等。模式實際上是壹種工具,是過去人們解決某壹類問題的經驗總結,所以我們可以在設計活動中應用各種設計模式,但是在應用這些模式之前壹定要把問題分析清楚,否則可能會出現“牛頭不對馬嘴”的現象。成功的項目總有相似之處,失敗的項目有各自的失敗之處。好的軟件架構設計壹定是成功項目的相似之處。我們沒有做好軟件架構設計的原因是什麽?