架構決定成敗算法
軟件架構是軟件產品、軟件系統設計當中的主體結構和主要矛盾。任何軟件都有架構,哪怕一段短小的HelloWorld程序。軟件架構設計的成敗決定了軟件產品和系統研發的成敗。軟件架構自身所具備的屬性和特色,決定了軟件架構設計的複雜性和難度。編程
這幾年流行一個說法(管理諺語):「細節決定成敗」,這句話其實只說對了一半。細節確實很重要,不少項目、產品就輸在細節的執行上。一方面,戰術細節當然很重要,但另外一方面,戰略全局也一樣重要,對應的咱們能夠說:「戰略決定成敗」。戰略性失敗,就比如下一盤圍棋,局部下得再漂亮、再凌厲,若是罔顧大盤,己方連空都不夠了,還有官子(細節)獲勝的機會嗎?必然是中盤告負。設計模式
相似地,正確的軟件架構設計,應該既包括戰略全局上的設計,也包括戰術細節(關鍵路徑)上的設計。有一種錯誤的觀點認爲,軟件架構設計只要分分層和包,畫一個大致的輪廓草圖,就完事了。這種「紙上談兵」型的架構師行爲是很是有害的。事實上,既然軟件架構是軟件建築的主體結構、隱蔽工程、承重牆和要害部位,那麼軟件架構也必然要落實到實際的算法和代碼,不但要有實現代碼,還要包括對這部分架構進行測試的代碼,以保證得到高質量的、知足各類功能和非功能質量屬性要求的架構。除了完成概念、模型設計外,軟件架構師必定要參與實際的編碼、測試和調試,作一位真正的hands-on practitioner,這已經成爲了敏捷軟件工程所倡導的主流文化。架構
兩個架構框架
咱們在平常的軟件產品和系統開發中,實際上會遇到兩種、兩個部分的軟件架構,即待開發的應用部分的軟件架構(簡稱「應用架構」),以及既有的基礎平臺部分的軟件架構(簡稱「基礎架構」)。這兩部分架構之間是互爲依賴、相輔相成的關係,它們共同組成了整個軟件產品和系統的架構。編程語言
基礎架構的例子包括:.NET和J2EE等主流的基礎平臺和各類公共應用框架,由基礎庫API、對象模型、事件模型、各類開發和應用的擴展規則等內容組成。咱們只有熟悉基礎架構的構造細節、應用機理,纔能有效地開發出高質量、高性能的上層應用。然而,開發一個面向最終用戶的軟件應用系統和產品,僅僅掌握通常的計算機高級編程語言知識和基礎平臺架構、API的使用知識顯然是不夠的,咱們還須要根據客戶應用的類型和特色,在基礎架構之上,設計出符合用戶要求的高質量應用軟件。函數
熟悉OOA、OOD抽象建模技術、設計原則以及架構模式和設計模式等等方法技術,不但有助於咱們更好地理解和利用基礎平臺架構,也有助於咱們設計開發出更高質量的應用軟件架構。工具
風險驅動、敏捷迭代的架構設計與開發性能
軟件架構將隨着軟件產品和系統的生命週期而演化,其生命期每每超過了一個項目、一次發佈,甚至有可能長達數年之久,於是軟件架構不管對於客戶仍是開發商來講都是一項極其重要的資產。測試
軟件架構的設計應該遵循什麼樣的開發過程?或者說,有沒有更好的、成熟的軟件架構設計和開發過程?回答是,21世紀的軟件架構設計應該優先採用敏捷迭代的開發方式和方法。與傳統作法不一樣,敏捷迭代開發主張軟件架構採用演進式設計(evolutionary design),一個軟件產品或系統的架構是經過屢次迭代,乃至屢次發佈,在開發生命週期中逐步創建和完善起來的。
好的軟件架構不是一蹴而就的。在架構設計開發過程當中,咱們應該儘可能避免瀑布式思惟,經過一個「架構設計階段」來完成系統的架構設計乃至詳細設計,而後再根據架構圖紙和模型,在「編碼實現階段」按圖索驥進行架構的編碼與實現。這種傳統作法的錯誤在於認爲軟件架構就是圖紙上的模型,而不是真正能夠高質量執行的源代碼。幾十年的軟件工程實踐代表,沒有通過代碼實現、測試、用戶確認過的架構設計,每每會存在着不可靠的臆想、猜想和過分設計、過分工程,極易形成浪費和返工,致使較高的失敗率。
風險是任何可能阻礙和致使軟件產品/系統研發失敗的潛在因素和問題。軟件架構是軟件產品和系統研發的主要矛盾和主要技術風險,軟件架構的質量決定了整個軟件系統和產品的質量。不肯定性每每是軟件架構設計當中一種最大的潛在風險。所以,軟件架構的設計與開發應該遵循風險驅動的原則,在整個開發生命週期內至始至終維護一張風險問題清單,隨着迭代的前進,根據風險的實時動態變化,首先化解和處理最主要的架構風險,再依次化解和處理次要的架構風險。
架構設計的可視化建模
軟件架構設計的難度源於軟件設計問題自己的複雜性,一個複雜的軟件系統每每存在大量複雜的、難於被人類所理解的細節和不肯定因素。抽象與建模是人類自誕生以來就已掌握的理解復瑣事物的方法,於是人類所從事的軟件設計工做本質上也是一個不斷建模的過程。咱們能夠經過各類抽象的模型和視圖,從各個不一樣層次、宏觀和微觀的角度來理解複雜的軟件架構,以保證做出正確和有效的設計。
有人認爲:「軟件架構就是源代碼(source codes)」以及「源代碼就是設計」。這種說法實際上是片面的。什麼是真正的軟件?咱們知道,最終能夠在電腦上執行的真正的軟件實際上是二進制代碼0和1,藉助編譯器咱們把高級編程語言翻譯成底層的彙編語言、機器語言等,沒有人能直接、完整地看到二進制程序在CPU上的實際運行情況(runtime),人們大多隻能經過各類調試工具、窗口視圖等方式來間接地動態觀察這些真正的軟件的運行片斷。所以,Java、C#、C++ 等等設計時(design time)源代碼在本質上也是一種模型,雖然是一種經處理後可執行的靜態模型,但顯然它們並非真實軟件和軟件架構的所有。可見,源代碼模型(有時也叫實現模型)與UML模型其實都是軟件架構的一種模型(邏輯反映),差異就在於抽象層次的不一樣。完整的軟件架構(建築)不只僅包括源代碼(實現模型),還包括了需求模型、分析模型、設計模型、實現模型和測試模型等等許多模型,軟件架構自己就是一組模型的集合。
UML、SysML是當前國際上流行的軟件/系統架構可視化建模語言。在編寫實際的代碼以前,利用包圖、類圖、活動圖、交互圖、狀態圖等等各類標準圖形符號對軟件架構進行建模,探討和交流各類可行的設計方案,發現潛在的設計問題,保證具體編碼實現以前抽象設計的正確性,被實踐證實是一種很是有效和高效、敏捷的工做方式。
架構設計的重用
重用(Reuse)是在軟件工程實踐中得到高效率、高質量產品和系統開發的一種基本手段和主要途徑,經過有組織的、系統和有效的重用,咱們每每能夠得到10倍率以上的效率提高。而一個優秀的、有長久生命力的軟件架構(比方主流的一些框架軟件),其自己或其組件被重用的次數越多,其體現的價值也就越大。
軟件重用有各類不一樣的範圍、層次、粒度和類型,從函數重用、類重用、構件/組件重用、庫(API)重用,到框架重用、架構重用、模式重用,再到軟件設計知識、思想的重用等等,重用的效能和效果各有不一樣。
軟件工程通過幾十年的發展,已經積累了大量的軟件架構模式和設計模式,它們記載、蘊藏了大量成熟、已經驗證的軟件設計知識、思想和經驗。咱們平時對各類基礎平臺、主流框架和API的應用和調用,自己就是一種最爲廣泛的重用形式。而一個優秀、成熟的軟件研發組織,必然會在平常開發中注意收集各類軟件設計知識和經驗,創建和維護基於架構模式和設計模式等內容的軟件重用知識庫,積極主動和頻繁地運用各類軟件模式來解決實際工程問題。
框架(Framework)是一類具備高可重用度的軟件,針對某一類應用或領域,它們具備很是靈活的、高度可擴展的軟件架構。那麼,如何才能設計出可重用的軟件架構或其組件?藉助於OOA、OOD等抽象分析和設計技術是一種重要的方法。人們在實踐中發現,每每越抽象的東西,其適應面也就越廣,可重用度也就越高;相反,越具體的東西,其適應面也就越窄,可重用度也就越低。重用,意味着充分利用現成、既有的東西、成果來解決新問題或重複的問題,以「不變」應「萬變」。在軟件架構設計中,應該主動地區分軟件架構中的「不變」與「可變」之處,系統地管理好這些穩定點和變化點以適應將來的變化,這也是提升軟件架構重用度、得到高質量框架設計的一種重要方法。
架構設計的權衡
與其它全部工程行業同樣,軟件工程本質上也是一門講究權衡的科學和藝術。軟件架構設計的最難之處每每在於如何在各類相互競爭、矛盾的制約條件之下,做出巧妙的最佳權衡。軟件架構設計的權衡水平,也是最能體現軟件架構師的設計經驗、能力和技巧的地方。
在軟件開發和軟件架構的設計過程當中,從選擇平臺,到選擇語言,選擇框架,選擇設計模式,選擇工具…等等,咱們無時不刻都須要權衡,對各類候選項做出合理評判。在架構師帶領下,軟件研發團隊每每還須要對近期目標與遠期目標、質量與速度和效率、質量與成本、功能與性能、靈活性與複雜性…等等許多彼此矛盾的設計選項、因素和約束進行細緻、當心和理性的權衡。
理性權衡意味着科學決策。進行有效的架構設計權衡,離不開科學的方法,也就是如何運用定量分析和定性分析相結合的方法、因果邏輯和根源分析等等技術,找到最終的甜點(Sweet Spot)。許多時候,可否在很短的時間內。