#讀後感#一本實用性很強的架構入門書籍。內容有深有淺,涉及面廣,幫我們樹立一個架構設計的全域觀。
本書已讀完,把讀後感放在最前面,以下是詳細的讀書筆記。
#讀書筆記# 我們將軟體架構概念分為兩大流派:組成派和決策派。
#讀書筆記# 組成派:軟體系統的架構將系統描述為計算群組件及組件之間的互動。
#讀書筆記# 決策派:軟體架構包含了關於以下問題的重要決策:軟體系統的組織;選擇組成系統的結構元素和它們之間的介面,以及當這些元素相互協作時所體現的行為;如何組合這些元素,使它們逐漸合成為更大的子系統;用於指導這個系統組織的架構風格:這些元素以及它們的介面、協作和組合。——1
#讀書筆記# 決策派:軟體架構並不僅僅注重軟體本身的結構和行為,還注重其他特性:使用、功能性、效能、彈性、重用、可理解性、經濟和技術的限制及權衡,以及美學等。——2
#讀書筆記# “架構決策是分層次依次展開的”還表現在:決策制定的順序往往是先制定技術無關的決策,後制定技術相關的決策,後者在前者的指導下進行。
#讀書筆記# 兩個流派的觀點可以簡單概括成:組成派“架構 = 組件 + 互動”,決策派“架構 = 重要決策集”。它們雖然角度不同,但卻相輔相成。
#讀書筆記# 架構是軟體,架構不是軟體。架構是系統或子系統的半成品。軟體架構不是軟體,而是關於軟體如何設計的重要決策。軟體架構是比具體代碼高一個抽象層次的概念。架構勢必被代碼所體現和遵循,但任何一段具體的代碼都代表不了架構。
#讀書筆記# 產品線架構一定要文檔化是有道理的。
#讀書筆記# 軟體架構師必須牢記:關注“軟體運行期品質屬性”,為開發人員而設計。
#讀書筆記# Philippe Kruchten在其著作《Rational統一過程引論》中寫道:一個架構視圖是對於從某一視角或某一點上看到的系統所作的簡化描述,描述中涵蓋了系統的某一特定方面,而省略了與此方面無關的實體。
#讀書筆記# 軟體架構的每個視圖分別關注不同的方面,針對不同的目標和用途。
#讀書筆記# 從概念性架構到實際架構,先設計概念性架構,構思關鍵問題的解決方案策略;再進行實際架構的設計,以保證為開發提供足夠的指導和限制......這符合人類解決問題的規律,因此被廣泛採用。
#讀書筆記# 易用性、效能、延展性、持續可用性、魯棒性、安全性、可擴充性、可重用性、可移植性、易理解性和易測試性等都可能是軟體的品質屬性需求。這些品質屬性之間存在一定的相互矛盾的情況。
#讀書筆記# 制定軟體架構設計策略:策略一,全面認識需求;策略二,關鍵需求決定架構;策略三,多視圖探尋架構;策略四,儘早驗證架構。
#讀書筆記# 高來高去式的架構設計大致有如下三種表現:癥狀一,缺失重要架構視圖;癥狀二,淺嘗輒止、不夠深入;癥狀三,名不副實的分層架構。
#讀書筆記# 關於軟體架構到底要設計到什麼程度,可以歸納為兩句話:由於項目的不同、Team Dev情況的不同,軟體架構的設計程度會有不同;軟體架構應當為開發人員提供足夠的指導和限制。
#讀書筆記# 囫圇吞棗地認為“需求就是使用者的要求”絕對是不夠的。
#讀書筆記# 需求分析致力於搞清楚軟體系統要“做什麼”,而系統分析更關注“怎麼做”的問題。
#讀書筆記# 功能需求影響架構,而架構必須適應功能需求。但功能需求並不能決定架構,這是顯而易見的。
#讀書筆記# 約束性需求最為特殊,它可能產生的影響有3種:(1)作為架構設計時必須遵守的限制條件;(2)導致軟體系統必須提供某些功能需求;(3)導致軟體系統必須滿足某些約束性需求。(參見圖10-8)
#讀書筆記# 用例的名稱應該從參與者的角度進行描述,並以動詞開頭,這樣一來通過“讀圖”可以清晰地獲得使用案例圖的語義。
#讀書筆記# 使用案例圖最重要的元素是參與者(Actor)和用例(Use Case)。
#讀書筆記# 用例簡述,就是通過簡短的文字對用例的功能進行描述;一般而言,用例簡述都應包含成功情境的簡單描述。
#讀書筆記# 用例規約是對用例的詳細描述,一般包括簡要說明、主事件流、備選事件流、前置條件、後置條件和優先順序等。用例規約的主要目的是界定軟體系統的行為需求。
#讀書筆記# 使用案例圖從總體上反映了使用者需求,而用例簡述和用例規約分別是行為需求的簡化描述和詳細描述。至於用例實現,已屬於設計範疇了。
#讀書筆記# 需求變化波及不同需求工件的規律:使用案例圖作為功能需求的泛而不深的總體描述,它是比較穩定的;用例簡述不涉及細節,因此也比較穩定;用例規約通過互動序列的方式描述功能需求,受需求變化影響較大。
#讀書筆記# 必須聰明地應付需求變更:推後用例細化;激發需求變更。
#讀書筆記# 架構師首要的第一步是做需求分析,涉及到的文檔或方法依次有:需求採集卡、願景與範圍文檔、特性列表、使用案例圖、用例簡述、用例規約、原型啟發需求、需求驗證、軟體需求規格說明書(含非功能需求)。
#讀書筆記# 領域模型對軟體架構乃至整個軟體系統開發工作的作用可以歸納為3點:探索複雜問題、固化領域知識;決定功能範圍、影響可擴充性;提供交流基礎、促進有效溝通。
#讀書筆記# 關鍵性的第一步是縮小範圍。
#讀書筆記# 窮兵黷武還是擇戰而鬥?
#讀書筆記# 關鍵需求決定架構,其餘需求驗證架構。
軟體需求的類型
軟體品質屬性分類方式
品質屬性關聯性矩陣
調整後的品質屬性關聯性矩陣
確定對軟體架構關鍵需求的步驟
概念性架構設計大致可以分為如下三步:
第一步,魯棒性分析。
第二步,引入架構模式。
第三步,品質屬性分析。
架構模式現代分類的經典圖書《面向模式的軟體體繫結構》,1996年出版。
各層之間的單向依賴又可以分為兩種:嚴格的分層架構要求第n層只能被第n+1層調用,與此相對的是不嚴格的分層架構,第n層可以被位於其上層的任意一層調用。
在概念性架構設計時,功能需求是魯棒性分析最主要的輸入,而品質屬性需求是品質屬性分析的最主要的輸入。
“屬性——情境——決策”表方法提倡通過一組具體情境將要達到的品質屬性需求目標細化,再根據這些實實在在的情境制定架構決策。
“屬性——情境——決策”表方法使軟體架構設計的決策過程從“黑盒”變成了“灰盒”,這樣做有以下好處:
1.可操作性強。
2.避免過度設計。
3.便於系統升級時參考。
一般而言,邏輯架構的設計應完成下列工作:
- 細化功能單元;
- 發現通用機制;
- 細化領域模型;
- 確定子系統介面和互動機制。
機制(Mechanism)是模式的執行個體。機制必須進一步細化才能成為特定模型中的協作,因此,機制是獨特上下文中重複出現的問題的特定解決方案。
進程被稱為“重量級控制流程”,因為它既是處理機資源的分配單位,又是其他電腦資源的分配單位。線程則被稱為“輕量級控制流程”,它僅僅是處理機資源的分配單位。一個進程內可以包含多個線程,這些線程共用所在進程的資源。
根據開發原型的目的是類比系統運行時的概貌、還是縱深地驗證一個具體的技術問題,可以將原型法分為兩類:水平原型和垂直原型。
有些原型用過之後是註定要被拋棄的,而有些原型我們則希望把它們保留下來作為正式開發的基礎。我們又可以將原型法分為兩類:拋棄原型和演化原型。
驗證架構有兩種方法——原型法和架構法。
架構原型對功能性需求的實現非常有限,那麼我們“結構描述驗證”要驗證什嗎?答案是要驗證架構對品質屬性需求的支援程度。
架構原型所實現的有限的功能需求應經過細心挑選,這些功能要麼是使用者“最關心的”,要麼是架構師“最擔心的”。
“見繼承不是繼承”, 在這個階段的人,腦中的興奮點是“設計”,是職責分配、介面設計、可重用性、可擴充性、耦合度、彙總度等這些設計層的概念。
耦合是依賴的同義字,被定義為“兩個元素之間的一種關係,其中一個元素變化,導致另一個元素變化”。
混入類的作用在於:它不僅可以提高功能的重用性,減小代碼冗餘;而且還可以使相關的“行為”集中在一個類中,而不是分布到多個類中,避免了所謂的“代碼分散”和“代碼交織”問題,提高了可維護性。
不會“在實際中”造成危害的依賴關係,都是良性依賴;依賴的“理論危害”不一定成為“實際危害”,反之亦然。這就是良性依賴原則。
“物件導向設計5大原則”和良性依賴原則在應付變化方面的作用:
單一職責原則(Single-Responsibility Principle)。“對一個類而言,應該僅有一個引起它變化的原因”。本原則是我們非常熟悉地“高內聚性原則”的引申,但是通過將“職責”極具創意地定義為“變化的原因”,使得本原則極具可操作性,盡顯大師風範。同時,本原則還揭示了內聚性和耦合性是“一物兩面”的關係,為了降低耦合性,基本途徑就是提高內聚性;如果一個類承擔的職責過多,那麼這些職責就會相互依賴,一個職責的變化可能會影響另一個職責的履行。其實OOD的實質,就是合理地進行類的職責分配。
開放封閉原則(Open-Closed Principle)。“軟體實體應該是可以擴充的,但是不可修改”。本原則緊緊圍繞變化展開,變化來臨時,如果不必改動軟體實體的原始碼,就能擴充它的行為,那麼這個軟體實體的設計就是滿足開放封閉原則的。如果我們預測到某種變化,或者某種變化發生了,我們應當建立抽象來隔離以後發生的同類變化。在Java中,這種抽象指抽象基類或介面;在C++中,這種抽象是指抽象基類或純抽象基類。當然,沒有對所有情況都貼切的模型,我們必須對軟體實體應該面對的變化做出選擇。
Liskov替換原則(Liskov-Substitution Principle)。“子類型必須能夠替換掉它們的基底類型”。本原則和開放封閉原則關係密切,正是子類型的可替換性,才使得使用基底類型的模組無需修改就可擴充。Liskov替換原則從基於契約的設計演化而來,契約通過為每個方法聲明“先驗條件”和“後驗條件”;定義子類時,必須遵守這些“先驗條件”和“後驗條件”。當前,基於契約的設計發展勢頭正勁,對實現“軟體工廠”的“組裝生產”夢想是一個有力的支援。
依賴倒置原則(Dependency-Inversion Principle)。“抽象不應依賴於細節,細節應該依賴於抽象”。本原則幾乎就是軟體設計的正本清源之道。因為人解決問題的思考過程是先抽象後具體,從籠統到細節的,所以我們先生產出的勢必是抽象程度比較高的實體,而後才是更加細節化的實體。於是,“細節依賴於抽象”就意味著後來的依賴於先前的,這是自然而然的重用之道。而且,抽象的實體代表著籠而統之的認識,人們總是比較容易正確認識它們,而且它們本身也是不易變的,依賴於它們是安全的。依賴倒置原則適應了人類認識過程的規律,是物件導向設計的標誌所在。
介面隔離原則(Interface-Segregation Principle)。“多個專用介面優於一個單一的通用介面”。本原則是單一職責原則用於介面設計的自然結果。一個介面應該保證,實現該介面的執行個體對象可以只呈現為單一的角色;這樣,當某個客戶程式的要求發生變化,而迫使介面發生改變時,影響到其他客戶程式的可能性最小。
良性依賴原則。“不會在實際中造成危害的依賴關係,都是良性依賴”。通過分析不難發現,本原則的核心思想是“務實”,很好地揭示了極限編程(Extreme Programming)中“簡單設計”和“重構”的理論基礎。本原則可以協助我們抵禦“物件導向設計5大原則”以及設計模式的誘惑,以免陷入過度設計(Over-engineering)的尷尬境地,帶來不必要的複雜性。
如果兩個或更多事物中的一個發生變化,不會影響其他事物,這些事物就是正交的。正交思維最有益的用處之一,是用於分類。
根據這個模式是應該推崇的還是應該避免的,又可將它分為“模式”與“反模式”兩類。經驗不一定正確,反模式就是對“不要那麼做”的歸檔。
UML推薦書籍:
- 《UML風格》一書,彙集了很多繪製UML圖的專家級建議。
- Peter Coad大師的著作《Java Modeling In Color With UML:Enterprise Components and Process》中講述的彩色建模方法—— 一種領域建模方面的優秀技術。
根據持續反饋來進行決策的時機,叫做裡程碑(Milestone)。裡程碑有兩種,階段結束對應的裡程碑叫做主要裡程碑(Major milestone);迭代結束對應的裡程碑叫做次要裡程碑(Minor milestone)。
軟體工程概念性模型
將CMM定位為“過程開發與改進的需求和測試方案”。
RUP剪裁大家討論的比較多了,有興趣的讀者可以閱讀本書參考文獻中所列的《隨需而變的RUP》一文。
全書讀完,更新結束。