1. 軟件架構(gòu)概述 1.1 什么是軟件架構(gòu) ◎ 軟件架構(gòu)的概念很混亂。如果你問(wèn)五個(gè)不同的人,可能會(huì)得到五種不同的答案。 ◎ 軟件架構(gòu)概念主要分為兩大流派: 組成派:軟件架構(gòu) = 組件 + 交互。 決策派:軟件架構(gòu) = 重要決策集。 ◎ 組成派和決策派的概念相輔相成。 1.2 軟件架構(gòu)和子系統(tǒng)、框架之間的關(guān)系 ◎ 復(fù)雜性是層次化的。 --《人月神話》 ◎ 好的架構(gòu)設(shè)計(jì)必須把變化點(diǎn)錯(cuò)落有致地封裝到軟件系統(tǒng)的不同部分(即關(guān)注點(diǎn)分離)。 通過(guò)關(guān)注點(diǎn)分離,達(dá)到“系統(tǒng)中的一部分發(fā)生了變化,不會(huì)影響其他部分”的目標(biāo)。 ◎ 軟件單元的粒度: * 粒度最小的單元通常是“類”。 * 幾個(gè)類緊密協(xié)作形成“模塊”。 * 完成相對(duì)獨(dú)立的功能的多個(gè)模塊構(gòu)成了“子系統(tǒng)”。 * 多個(gè)子系統(tǒng)相互配合才能滿足一個(gè)完整應(yīng)用的需求,從而構(gòu)成了軟件“系統(tǒng)”。 * 一個(gè)大型企業(yè)往往使用多套系統(tǒng),多套系統(tǒng)通過(guò)互操作形成“集成系統(tǒng)”。 ◎ 軟件單元的粒度是相對(duì)的。同一個(gè)軟件單元,在不同場(chǎng)景下我們會(huì)以不同的粒度看待它。 ◎ 架構(gòu)(Architecture)不等于框架(Framework)。 框架只是一種特殊的軟件,框架也有架構(gòu)。 ◎ 可以通過(guò)架構(gòu)框架化達(dá)到“架構(gòu)重用”的目的,如很多人都在用 Spring 框架提供的控制反轉(zhuǎn)和依賴注入來(lái)構(gòu)建自己的架構(gòu)。 1.3 軟件架構(gòu)的作用 ◎ 如果一個(gè)項(xiàng)目的系統(tǒng)架構(gòu)(包括理論基礎(chǔ))尚未確定,就不應(yīng)該進(jìn)行此系統(tǒng)的全面開發(fā)。-- Barry Boehm,《Engineering Context》 ◎ 一個(gè)缺陷充斥的系統(tǒng),將始終是一個(gè)缺陷充斥的系統(tǒng)。-- Timothy C. Lethbridge,《面向?qū)ο筌浖こ獭? ◎ 軟件架構(gòu)設(shè)計(jì)為什么這么難? 因?yàn)樗强缭浆F(xiàn)實(shí)世界與計(jì)算機(jī)世界之間鴻溝的一座橋。 軟件架構(gòu)設(shè)計(jì)要完成從面向業(yè)務(wù)到面向技術(shù)的轉(zhuǎn)換,在鴻溝上架起一座橋梁。 需求 -> 架構(gòu)設(shè)計(jì) -> 軟件架構(gòu) -> 系統(tǒng)開發(fā) -> 軟件系統(tǒng) ~~~~~~~~ ~~~~~~~~ ◎ 軟件架構(gòu)對(duì)新產(chǎn)品開發(fā)的作用: * 上承業(yè)務(wù)目標(biāo)。 * 下接技術(shù)決策。 * 控制復(fù)雜性。 先進(jìn)行架構(gòu)設(shè)計(jì),后進(jìn)行詳細(xì)設(shè)計(jì)和編碼實(shí)現(xiàn),符合“基于問(wèn)題深度分而治之”的理念。 * 組織開發(fā)。 軟件架構(gòu)方案在小組中間扮演了“橋梁”和“合作契約”的作用。 * 利于迭代開發(fā)和增量交付。 以架構(gòu)為中心進(jìn)行開發(fā),為增量交付提供了良好的基礎(chǔ)。在架構(gòu)經(jīng)過(guò)驗(yàn)證之后,可以專注于功能的增量提交。 * 提高質(zhì)量。 ◎ 軟件架構(gòu)對(duì)軟件產(chǎn)品線開發(fā)的作用: * 固化核心知識(shí); * 提供可重用資產(chǎn); * 縮短推出產(chǎn)品的周期; * 降低開發(fā)和維護(hù)成本; * 提高產(chǎn)品質(zhì)量; * 支持批量定制。 ◎ 軟件產(chǎn)品線:指具有一組可管理的、公共特性的、軟件密集性系統(tǒng)的集合,這些系統(tǒng)滿足特定的市場(chǎng)需求或任務(wù)需求,并且按照預(yù)定義方式從一個(gè)公共的核心資產(chǎn)集開發(fā)得到。 軟件產(chǎn)品線架構(gòu):針對(duì)一個(gè)公司或組織內(nèi)的一系列產(chǎn)品而設(shè)計(jì)的通用架構(gòu)。 2. 軟件架構(gòu)設(shè)計(jì)方法 2.1 軟件架構(gòu)為誰(shuí)而設(shè)計(jì) ◎ 架構(gòu)師應(yīng)當(dāng)為項(xiàng)目相關(guān)的不同角色而設(shè)計(jì): * 架構(gòu)師要為客戶負(fù)責(zé),滿足他們的業(yè)務(wù)目標(biāo)和約束條件。 * 架構(gòu)師要為用戶負(fù)責(zé),滿足他們關(guān)心的功能需求和運(yùn)行期質(zhì)量屬性。 * 架構(gòu)師必須顧及處于協(xié)作分工“下游”的開發(fā)人員。 * 架構(gòu)師必須考慮“周邊”的管理人員,為他們進(jìn)行分工管理、協(xié)調(diào)控制和評(píng)估監(jiān)控等工作提供清晰的基礎(chǔ)。 2.2 五視圖法 ◎ 什么是軟件架構(gòu)視圖? 軟件架構(gòu)視圖是對(duì)于從某一視角看到的系統(tǒng)所作的簡(jiǎn)化描述,描述中涵蓋了系統(tǒng)的某一特定方面,而省略了與此無(wú)關(guān)的其他方面。 ◎ 軟件架構(gòu)要涵蓋的內(nèi)容和決策太多了,超過(guò)了人腦“一蹴而就”的能力范圍,因此宜采用“分而治之”的辦法。即通過(guò)不同的視圖來(lái)描述架構(gòu)。 ◎ 軟件架構(gòu)的五視圖法: * 邏輯架構(gòu) 邏輯架構(gòu)關(guān)注功能。其設(shè)計(jì)著重考慮功能需求。 * 開發(fā)架構(gòu) 開發(fā)架構(gòu)關(guān)注程序包。其設(shè)計(jì)著重考慮開發(fā)期質(zhì)量屬性,如可擴(kuò)展性、可重用性、可移植性、易理解性和易測(cè)試性等。 * 運(yùn)行架構(gòu) 運(yùn)行架構(gòu)關(guān)注進(jìn)程、線程、對(duì)象等運(yùn)行時(shí)概念,以及相關(guān)的并發(fā)、同步、通信等問(wèn)題。 其設(shè)計(jì)著重考慮運(yùn)行期質(zhì)量屬性,例如性能、可伸縮性、持續(xù)可用性和安全性等。 * 物理架構(gòu) 物理架構(gòu)關(guān)注軟件系統(tǒng)最終如何安裝或部署到物理機(jī)器。其設(shè)計(jì)著重考慮“安裝和部署需求”。 * 數(shù)據(jù)架構(gòu) 數(shù)據(jù)架構(gòu)關(guān)注持久化數(shù)據(jù)的存儲(chǔ)方案。其設(shè)計(jì)著重考慮“數(shù)據(jù)需求”。 2.3 從概念性架構(gòu)到實(shí)際架構(gòu) ◎ 少就是多 (Less is more.)。 -- 密斯·凡德羅 ◎ 概念性架構(gòu)是對(duì)系統(tǒng)設(shè)計(jì)的最初構(gòu)想。 ◎ 一般來(lái)說(shuō),實(shí)際的軟件架構(gòu)設(shè)計(jì)過(guò)程是,先進(jìn)行概念性架構(gòu)的設(shè)計(jì),把最關(guān)鍵的設(shè)計(jì)要素和交互機(jī)制確定下來(lái),然后再考慮具體技術(shù)的運(yùn)用,設(shè)計(jì)出實(shí)際架構(gòu)。 2.4 架構(gòu)設(shè)計(jì)中的關(guān)鍵要素及解決策略 ◎ 策略是制勝的關(guān)鍵。-- 張明正,《擋不住的趨勢(shì)》 ◎ 最好的軟件開發(fā)人員都知道一個(gè)秘密:美的東西比丑的東西創(chuàng)建起來(lái)更廉價(jià),也更快捷。-- Robert C. Martin, 《軟件之美》 ◎ 時(shí)間就是系統(tǒng)架構(gòu)的生命。-- Philippe Kruchten ◎ 方法產(chǎn)生于恐懼。 ◎ 面對(duì)時(shí)間緊迫的壓力,我們有理由質(zhì)疑那種不顧時(shí)間花銷、一味追求軟件架構(gòu)高質(zhì)量的做法。軟件架構(gòu)是軟件系統(tǒng)質(zhì)量的核心,必須足夠重視,但在不適當(dāng)?shù)臅r(shí)候“用時(shí)間換完美”會(huì)毀掉整個(gè)項(xiàng)目。 ◎ 架構(gòu)設(shè)計(jì)并非“好的就是成功的”,而是“適合的才是成功的”。 ◎ 軟件架構(gòu)設(shè)計(jì)中的關(guān)鍵要素及解決策略: 關(guān)鍵要素 策略 ------------------------------------ ----------------- 1. 是否遺漏了至關(guān)重要的非功能需求? 全面認(rèn)識(shí)需求。 2. 能否馴服數(shù)量巨大且頻繁變化的需求? 關(guān)鍵需求決定架構(gòu)。 3. 能否從容地設(shè)計(jì)軟件架構(gòu)的不同方面? 多視圖探尋架構(gòu)。 4. 是否及早驗(yàn)證架構(gòu)方案并作出了調(diào)整? 及早驗(yàn)證架構(gòu)。 2.5 軟件架構(gòu)要設(shè)計(jì)到什么程度 ◎ 軟件系統(tǒng)的架構(gòu)涵蓋了整個(gè)系統(tǒng),盡管架構(gòu)的有些部分可能只有“一寸深”。-- Ivar Jacobson, 《統(tǒng)一軟件開發(fā)過(guò)程之路》 ◎ 軟件架構(gòu)是團(tuán)隊(duì)開發(fā)的基礎(chǔ)。 ◎ 軟件架構(gòu)要設(shè)計(jì)到什么程度? * 由于項(xiàng)目的不同、開發(fā)團(tuán)隊(duì)情況的不同,軟件架構(gòu)的設(shè)計(jì)程度會(huì)有不同。 * 軟件架構(gòu)應(yīng)當(dāng)為開發(fā)人員提供足夠的指導(dǎo)和限制。 ◎ 高來(lái)高去式架構(gòu)設(shè)計(jì)的癥狀: * 缺失重要架構(gòu)視圖。 遺漏了某些重要視圖,從而遺漏了對(duì)團(tuán)隊(duì)某些角色的指導(dǎo)。 * 淺嘗輒止、不夠深入。 將重大技術(shù)風(fēng)險(xiǎn)遺留到后續(xù)開發(fā)中。 * 名不副實(shí)的分層架構(gòu)。 對(duì)各層之間交互接口和交互機(jī)制的設(shè)計(jì)嚴(yán)重不足。 3. 軟件架構(gòu)設(shè)計(jì)過(guò)程 3.1 軟件架構(gòu)設(shè)計(jì)過(guò)程總覽 ◎ 一般的軟件過(guò)程: 概念化階段 -> 分析階段 -> 架構(gòu)設(shè)計(jì)階段 -> 并行開發(fā)與測(cè)試階段 -> 驗(yàn)收與交付階段 ──┬── ──┬─ ───┬── ────┬──── ───┬─── ↓ ↓ ↓ ↓ ↓ 愿景 需求 架構(gòu) 可執(zhí)行系統(tǒng) 交付的系統(tǒng) ◎ 軟件架構(gòu)設(shè)計(jì)過(guò)程: 需求分析 -> 領(lǐng)域建模 -> 確定關(guān)鍵需求 -> 概念性架構(gòu)設(shè)計(jì) -> 細(xì)化架構(gòu) -> 驗(yàn)證架構(gòu) │ │ └──────┬──────┘ └────┬───┘ │ │ 概念性架構(gòu) 實(shí)際架構(gòu) └───┬────┘ └───────┬──────┘ 分析階段 架構(gòu)設(shè)計(jì)階段 3.2 需求分析 3.2.1 幾個(gè)概念 ◎ 需求捕獲 vs 需求分析 vs 系統(tǒng)分析 * 需求捕獲是獲取知識(shí)的過(guò)程,知識(shí)從無(wú)到有。 * 需求分析是挖掘和整理知識(shí)的過(guò)程,它在已掌握知識(shí)的基礎(chǔ)上進(jìn)行。 * 系統(tǒng)分析?如果說(shuō)需求分析致力于“做什么”,那么系統(tǒng)分析則涉及“怎么做”。 3.2.2 架構(gòu)師必須掌握的需求知識(shí) ◎ 軟件架構(gòu)師不必是需求捕獲專家,也不必是編寫《軟件需求規(guī)格說(shuō)明書》的專家。 但他一定應(yīng)在需求分類、需求折衷和需求變更的研究方面是專家,否則他和其他軟件架構(gòu)師相比,就輸在了“起跑線”上。 ◎ 軟件需求的類型 ┌ 功能需求 ┌ 運(yùn)行期質(zhì)量屬性 軟件需求 ┤ ┌ 質(zhì)量屬性 ┤ └ 非功能需求 ┤ └ 開發(fā)期質(zhì)量屬性 └ 約束 ◎ 軟件質(zhì)量屬性分類方式 運(yùn)行期質(zhì)量屬性 * 性能 (Performance) * 安全性 (Security) * 易用性 (Usability) * 持續(xù)可用性 (Availability) * 可伸縮性 (Scalability) * 互操作性 (Interoperability) * 可靠性 (Reliability) * 魯棒性 (Robustness) 開發(fā)期質(zhì)量屬性 * 易理解性 (Understandability) * 可擴(kuò)展性 (Extensibility) * 可重用性 (Reusability) * 可測(cè)試行 (Testability) * 可維護(hù)性 (Maintainability) * 可移植性 (Portability) 3.3 領(lǐng)域建模 ◎ 就像《高效能人士的七個(gè)習(xí)慣》提到的“由內(nèi)而外全面造就自己”的觀點(diǎn)一樣,對(duì)待軟件開發(fā),要具備“由內(nèi)而外造就軟件”的理念。 ◎ 想讓軟件系統(tǒng)隨需應(yīng)變嗎?請(qǐng)給軟件一個(gè)支持變化的“心”。 ◎ 什么是領(lǐng)域模型? 領(lǐng)域模型是對(duì)實(shí)際問(wèn)題領(lǐng)域的抽象表示,它專注于分析問(wèn)題領(lǐng)域本身,發(fā)掘重要的業(yè)務(wù)領(lǐng)域概念,并建立業(yè)務(wù)領(lǐng)域概念之間的關(guān)系。 ◎ 領(lǐng)域建模和需求分析活動(dòng)是相互伴隨、互相支持、交疊演進(jìn)的。 ◎ 領(lǐng)域模型對(duì)軟件架構(gòu)乃至整個(gè)軟件系統(tǒng)開發(fā)工作的作用: * 探索復(fù)雜問(wèn)題、固化領(lǐng)域知識(shí); * 決定功能范圍、影響可擴(kuò)展性; * 提供交流基礎(chǔ)、促進(jìn)有效溝通。 3.4 確定關(guān)鍵需求 ◎ 功能、質(zhì)量和商業(yè)需求的某個(gè)集合“塑造”了架構(gòu)。-- Len Bass, 《軟件架構(gòu)實(shí)踐(第2版)》 ◎ 關(guān)鍵需求決定架構(gòu),其余需求驗(yàn)證架構(gòu)。 ◎ 什么是對(duì)軟件架構(gòu)關(guān)鍵的需求? * 關(guān)鍵的功能需求。 * 關(guān)鍵的質(zhì)量屬性需求。 * 關(guān)鍵的商業(yè)需求。 ◎ 如何確定關(guān)鍵需求? ┌> 確定關(guān)鍵功能需求 ┐ ● -> 全面整理需求 -> 分析約束性需求 ┤ ├> ● └> 確定關(guān)鍵質(zhì)量屬性需求 ┘ 3.5 概念性架構(gòu)設(shè)計(jì) ◎ 概念性架構(gòu)設(shè)計(jì)的步驟(這三個(gè)步驟以迭代方式進(jìn)行): 1. 魯棒性分析; 2. 引入架構(gòu)模式; 3. 質(zhì)量屬性分析。 3.5.1 魯棒性分析 ◎ 所謂魯棒性分析是這樣一種方法:通過(guò)分析用例規(guī)約中的事件流,識(shí)別出實(shí)現(xiàn)用例規(guī)定的功能所需的主要對(duì)象及其職責(zé),形成以職責(zé)模型為主的初步設(shè)計(jì)。 ◎ 魯棒性分析是從功能需求向設(shè)計(jì)方案過(guò)度的第一步,所獲得的初步設(shè)計(jì)是一種理想化的職責(zé)模型,它的重點(diǎn)是識(shí)別組成軟件系統(tǒng)的高級(jí)職責(zé)塊、規(guī)劃它們之間的關(guān)系。 ◎ 魯棒性分析填補(bǔ)了分析和設(shè)計(jì)之間的鴻溝。 ◎ 魯棒圖包含三種元素:邊界對(duì)象、控制對(duì)象和實(shí)體對(duì)象。(見書P196) 3.5.2 引入架構(gòu)模式 ◎ 較為經(jīng)典的幾種架構(gòu)模式: 分層、MVC、微內(nèi)核、基于元模型的架構(gòu)、管道-過(guò)濾器。 ◎ 關(guān)于架構(gòu)模式的幾點(diǎn)說(shuō)明: * 分層 避免名不副實(shí)的分層架構(gòu),即對(duì)各層之間交互接口和交互機(jī)制的設(shè)計(jì)嚴(yán)重不足。 * 微內(nèi)核 缺點(diǎn):設(shè)計(jì)和實(shí)現(xiàn)的復(fù)雜性;性能較低。 優(yōu)點(diǎn):擴(kuò)展性強(qiáng),可移植性強(qiáng),軟件系統(tǒng)的生命周期長(zhǎng)。 3.5.3 質(zhì)量屬性分析 ◎ “屬性-場(chǎng)景-決策”表方法。舉例如下: ┌────┬─────────┬─────────────────────┐ │屬性 │場(chǎng)景 │決策 │ ├────┼─────────┼─────────────────────┤ │可擴(kuò)展性│數(shù)據(jù)庫(kù)類型可替換 │建立數(shù)據(jù)庫(kù)存取層 │ ├────┼─────────┼─────────────────────┤ │ │允許加載第三方模塊│采用插件機(jī)制 │ ├────┼─────────┼─────────────────────┤ │... │... │... │ └────┴─────────┴─────────────────────┘ 3.6 細(xì)化架構(gòu)設(shè)計(jì) ◎ 架構(gòu)細(xì)化工作主要體現(xiàn)在基于五視圖方法進(jìn)行架構(gòu)細(xì)化: 約束 ↓ ┌───────┐ 領(lǐng)域模型 -> │基于五視圖方法│ 關(guān)鍵需求 -> │ │-> 架構(gòu)方案 概念架構(gòu) -> │ 進(jìn)行架構(gòu)細(xì)化 │ └───────┘ ↑ 經(jīng)驗(yàn) ◎ 架構(gòu)細(xì)化設(shè)計(jì)的工作內(nèi)容: ┌───────┬──────────────────────────┐ │ 架構(gòu)設(shè)計(jì)視圖 │ 設(shè)計(jì)任務(wù) │ ├───────┼──────────────────────────┤ │ 邏輯架構(gòu) │ 細(xì)化功能單元; │ │ │ 發(fā)現(xiàn)通用機(jī)制; │ │ │ 細(xì)化領(lǐng)域模型; │ │ │ 確定子系統(tǒng)接口和交互機(jī)制。 │ ├───────┼──────────────────────────┤ │ 開發(fā)架構(gòu) │ 確定要開發(fā)或直接利用的程序包之間的依賴關(guān)系; │ │ │ 確定采用的技術(shù); │ │ │ 確定采用的框架等。 │ ├───────┼──────────────────────────┤ │ 數(shù)據(jù)架構(gòu) │ 持久化數(shù)據(jù)存儲(chǔ)方案; │ │ │ 數(shù)據(jù)傳遞、數(shù)據(jù)復(fù)制、數(shù)據(jù)同步等策略(可選)。 │ ├───────┼──────────────────────────┤ │ 運(yùn)行架構(gòu) │ 確定引入哪些進(jìn)程與線程; │ │ │ 確定主動(dòng)對(duì)象、被動(dòng)對(duì)象,以及控制關(guān)系; │ │ │ 處理進(jìn)程線程的創(chuàng)建、銷毀、通信機(jī)制、資源爭(zhēng)用等; │ │ │ 協(xié)議設(shè)計(jì)。 │ ├───────┼──────────────────────────┤ │ 物理架構(gòu) │ 確定物理配置方案; │ │ │ 確定如何將目標(biāo)程序映射到物理節(jié)點(diǎn)。 │ └───────┴──────────────────────────┘ ◎ 邏輯架構(gòu)設(shè)計(jì)中,“發(fā)現(xiàn)通用機(jī)制”是應(yīng)被特別強(qiáng)調(diào)的。 機(jī)制(Mechanism)是模式的實(shí)例。機(jī)制是特定上下文中重復(fù)出現(xiàn)的問(wèn)題的特定解決方案。 具有良好架構(gòu)的系統(tǒng)具備概念完整性。它通過(guò)對(duì)系統(tǒng)架構(gòu)建立一種清晰的認(rèn)識(shí)來(lái)發(fā)現(xiàn)通用的抽象和機(jī)制。利用這種共性使最終產(chǎn)生的系統(tǒng)結(jié)構(gòu)更為簡(jiǎn)單。 3.7 實(shí)現(xiàn)并驗(yàn)證軟件架構(gòu) ◎ 好的策略必須是一再求證、測(cè)試、發(fā)現(xiàn)瑕疵漏洞,另想途徑或方法來(lái)彌補(bǔ)策略不足,有時(shí)甚至得全盤放棄,重新策劃。-- 張明正,《擋不住的趨勢(shì)》 ◎ 架構(gòu)原型對(duì)功能性需求的實(shí)現(xiàn)非常有限,那么“架構(gòu)驗(yàn)證”要驗(yàn)證什么? 答案是要驗(yàn)證架構(gòu)對(duì)質(zhì)量屬性需求的支持程度,包括運(yùn)行期質(zhì)量屬性和開發(fā)期質(zhì)量屬性。 ◎ 驗(yàn)證架構(gòu)的兩種方法: * 原型法。 對(duì)于項(xiàng)目型開發(fā),常采用“原型法”。即對(duì)一組架構(gòu)設(shè)計(jì)決策在非功能需求方面的滿足程度進(jìn)行驗(yàn)證。該原型往往是演進(jìn)型,而非拋棄型。 * 框架法。 對(duì)于產(chǎn)品型開發(fā),采用“框架法”有更多優(yōu)點(diǎn)。該方法將架構(gòu)設(shè)計(jì)方案用框架的形式實(shí)現(xiàn),并在此基礎(chǔ)上進(jìn)行評(píng)估驗(yàn)證。在框架實(shí)現(xiàn)后,在框架基礎(chǔ)上實(shí)現(xiàn)部分應(yīng)用 的功能,即實(shí)現(xiàn)一個(gè)小的垂直原型,從而進(jìn)行實(shí)際非功能測(cè)試和開發(fā)期質(zhì)量屬性評(píng)價(jià)。 |