《恰如其分的軟體架構》筆記摘要

九卷發表於2020-09-01

《恰如其分的軟體架構》 一書
其實讀起來感覺有點學術性質,換句話說,有點晦澀難懂。不知道是不是翻譯的問題。

書裡提倡的按風險驅動的架構設計,還是值得借鑑的設計方法。我的理解就是“問題驅動法”。
比如說目前業務有哪些難點,有哪些問題需要解決,用筆一一羅列出來,然後按照羅列的問題,
去選擇合適的技術,合適的架構,來解決這些問題。

什麼是軟體架構?

軟體架構就是系統設計,以及它對諸如效能、安全和可修改性等系統所產生的影響。
軟體架構抉擇很重要,架構是系統骨骼,直接影響質量屬性,並約束整個系統。

從某個角度來說,架構與功能可以互相組合,只是不同組合有不同表現效果而已。

利用模型和抽象概念去構建和解釋系統架構。

軟體設計可分為軟體架構和詳細設計。

軟體架構的定義,來自卡內基.梅隆大學軟體工程研究所(MEI)定義:

計算系統的軟體架構是解釋給系統鎖所需的結構體集合,其中包括:軟體元素、元素之間的相互關係,以及二者各自的屬性。

該定義的重點:元素、元素之間的關係以及元素的屬性。

架構是設計的巨集觀部分。

架構是必須在專案早期做出的一組設計決策。

軟體架構為什麼重要

軟體架構重要性在於它會影響整個軟體的系統。只有審慎的選擇架構,才能降低風險,避免失敗。

  1. 架構扮演者系統骨架的角色
  2. 架構影響質量屬性
  3. 架構與功能(基本上)正交的
  4. 架構還是對系統的約束

系統架構不僅要支援所需的功能,同時還能促進或者抑制諸如安全或效能等系統質量。
作者舉例:
人和馬的身體骨架都能夠運輸蘋果到市場的功能,但是運輸效率和數量上相差甚遠。

選擇一種架構使得系統能夠工作並不是難事,但滿足質量屬性方面,有的選擇是事半功倍,有的選擇則會事倍功半。

架構何時變得重要

解空間小:問題複雜,很難設計出好的解決方案,那麼架構就顯得尤為重要。

翻譯成 解,真不好理解

高的失敗風險:任何時候,失敗的風險越高,就越需要保證正確架構

難以實現的質量屬性:架構會影響質量屬性的能力。開發一個郵件系統並不難,然而,一般要求高效能支援百萬級使用者,就變得異常困難

我理解的質量屬性:就是架構的目標,比如高可用,安全性,可伸縮等等。翻譯成質量屬性也比較難理解。

全新領域:面對全新領域,或者對於設計者而言是全新領域,就需要對架構給予更多關注。

產品線:一些產品線會共享某一通用架構。

企業架構師:企業架構師是負責多個應用系統的開發者。他們並不會控制任何一個應用系統的功能。相反,他們會設計一個生態系統,位於其中的每個應用系統都為整個企業做出自己的貢獻。

應用架構師:應用架構師是單個系統的開發者。他們設計系統功能,而非架構。當然,他們也可以專注架構設計或提升架構的設計運用到應用系統中。

架構設計的方式有哪些?

1、不做預先設計:開發者一上來就寫程式碼。這也會發生設計,只不過是與編碼起頭並進
2、用一些時間比例來做設計:比如,10%用於架構設計,50%編碼,20%測試,10%整合
3、詳細的設計:一開始就做詳細架構設計,並形成詳細的架構文件
4、隨機應變方式:根據專案需求隨機做出決定,是否需要架構設計?多少時間用來做架構設計?

風險驅動模型

什麼是風險驅動模型:

我的風險是什麼? 用於降低這些風險的技術是什麼?風險是否化解,可以開始編碼了嗎?,這三問。

風險驅動模型歸納三個步驟:
1、識別風險,並排定優先順序
2、選擇並運用一組技術
3、評估風險降低的程度

專案領域典型的風險

如下圖:
project-risk

識別風險以及風險決策

  • 識別風險
    經驗豐富的開發者很容易識別風險,如果開發者缺乏經驗,或者對該領域不熟,怎麼辦?最容易辦法從需求開始,去尋找那些似乎難以實現的內容。不完整或容易引起誤解的質量屬性需求是最為常見的風險。
    捕獲風險並提供一份失敗場景的優先順序列表。
    必須認識到,及時竭盡全力,專案扔會面對一些未識別的風險。

  • 典型風險
    在某一領域工作一段時間後,你就會注意到一些典型風險,他們對於該領域大多數專案而言都是很常見的。

  • 決策風險優先順序
    由於風險有大有小,因此需要對他們進行優先順序排序。

技術
一段識別了風險,就運用期望的技術去降低風險。

我的舉例:比如,訪問量大了之後,資料庫可能抗不住,你會想到增加一層快取來降低對資料庫的直接訪問。

從分析到解決方案。

軟體工程以及其他領域中工程避險技術的若干示例

軟體工程 其他工程
運用設計模式或架構模式 應力計算
領域建模 斷點測試
吞吐量預估 熱分析
安全性評估 可靠性測試
原型測試 原型測試

風險驅動模型是以分析為目的的相關技術,他們都是過程性的,而且獨立的問題域。這些技術包括:
使用模型-層級圖、元件裝備模型以及部署模型;對效能、安全和可靠性進行分析的技術;利用各種架構風格,如client-server,pipe-and-filter(管道-過濾器)去實現某個緊迫的質量屬性需求。

設計是一個神祕的過程,只有大師才能實現從推理問題到解決方案的跨越。我們要從大師中學得這麼技藝。

做出技術合理決策公式

如果你面臨<某種風險>,可以考慮使用<某種技術>降低它。

利用你的若干知識把風險與技術之間做一個若干對映。

任何特定技術都擅長降低某些風險,而對於其他風險卻未必。

有些風險可以通過多種技術去緩解,而另外一些風險甚至需要發明一些技術才能解決。

我理解:這些技術往往是大公司發明的,因為他們的業務體量,需要新的技術才能解決。比如google發表的那3篇大資料論文。就改變了大資料處理領域。

一眼看去,總是很難判斷該運用哪些技術才是適合。每種技術都有其價值,卻未必是專案最需要的。

我理解:這就是專案技術選型難點之一。

技術選型指導原則

上面介紹了風險驅動模型,並主張根據所面對的風險去挑選技術。那如何才能做出合適的選型決策?

重要原則
1、首先,當面臨一個要解決的問題,而在其他情況下又遇到需要證明的問題,技術決策應該與具體需求相匹配
2、其次,某些通過類比模型解決,而其他問題,藉助分析模型解決,此時需要分辨不同模型之間差異
3、再次,採用特定型別的模型,才能有效分析問題。
4、最後,某些技術之間中存在著密切的關係

要求解的問題和要證明的問題:要求解的問題,找到答案就可以了;要證明的問題,需要找到所有情況為真,這比求解問題難的多。

舉例:“資料庫能否儲存多大一百個字元的名稱?”它屬於要求解的問題,為此問題編寫測試用例就很容易解出來。

“該系統是否一致符合該框架的應用程式程式設計介面?” 這就是需要要證明的問題。儘管可以做多種測試,但,仍然會有某些情況被忽略了。

我理解:上面說的是一些解決問題方法。但是做技術選擇還要考慮人和技術社群因數,公司技術人是否會這種技術,該技術社群是否成熟,成熟的標準就是遇到了問題,能有人熱心提供幫助。其次,就是該技術提供的解決方案是否與遇到的問題相匹配。最後,該技術後續升級發展,與公司業務發展週期是否相匹配。不要遇到那種純kpi專案,突然就停止開發。但公司業務還在發展,遇到問題怎麼辦?這也是選型的風險。

如何把握設計與架構的度

有人說架構就是一種平衡,在現階段下,“利益”的平衡和取捨。

架構設計越複雜,那麼,實現所花費的時間就越多,而需求變化又極快,所以必須平衡需求與架構之間衝突。
不需要識別出所有風險後,包括現在和以後的風險才開始架構,只要架構能滿足現在業務發展,並能應付未來1到2年的發展即可。

計劃式設計與演進式設計

演進式設計

從歷史過往來看,演進式架構飽受爭議,因為區域性而又不協調的設計決策會導致混亂,從而創造出一個大雜燴,既難維護,又難以進一步演進。然而,隨著敏捷實踐中的重構、測試驅動設計以及持續整合可以對付各種混亂問題。
重構(對程式碼進改進)清除了不協調的區域性設計,
測試驅動設計確保對系統更改不會導致系統丟失或破壞現有功能,
持續整合則為整個團隊提供了統一程式碼庫。

因為有上述種種實踐,一些人認為可以不用做計劃式設計。
其中,重構式克服演進式設計中大雜燴問題的主力。但,重構缺陷是,它並沒有為架構規模的轉換提供指導。

計劃式設計

演進式設計對立面就是計劃式設計。
它的總體思路是,在專案構建前,就非常詳細制定各種計劃。有時,它被稱為預先大量設計(BDUF)。

最小計劃式設計

最小計劃式設計 (little design up front,Martin,2009)。這是一種介於演進式設計和計劃式設計之間的一種設計方法。

在計劃式設計與演進式設計之間取得平衡是可能的。
一種方法是現在一些初步的計劃式設計,確保架構可以處理一些最大風險。在初始計劃式設計完成後,未來的需求變化往往通過區域性設計去處理,或採用演技式設計,前提是重構、測試驅動設計和持續整合等實踐在專案中已經展開起來。

理解過程變化

幾種開發模型的比較:

還有現在流行的 DevOps模型 ,開發運維一體化

風險驅動模型缺點

它能幫助我們決定何時可以停止架構設計,以及應到我們開展各種適當的架構活動。
但是,它並不擅長預測在設計上到底花多長的時間。

建模

工程師的目標是將現實世界的問題轉換為現實世界的解決方案。若是簡單問題,則無需抽象即可解決。然而,對於複雜的問題,越需要通過抽象來建模解決。
現實世界的問題在抽象模型中體現,在建模領域中解決,在將該解決方案對映到現實世界的解決方案。架構模型也是如此。

規模與複雜度需要抽象

模型為解決問題提供了洞察力和解決手段。

建立架構模型是一種理解和解決棘手問題的好方法,因為它可以去掉無關的細節,使得你能夠將注意力放在主要部分以及相關關係上,做出預測,評估候選方案。

模型忽略了細節。

站在巨人肩膀上,以前的巨人不僅為我們提供了可見的編譯器和資料庫,還提供了一套抽象的程式設計思維理論。一部分抽象概念已經植根與程式語言中--函式、類、模組等。其餘則包括元件、埠和聯結器。

領域模型、設計模型和程式碼模型

規範化模型結構頂部抽象層次追到的模型(領域),底部模型則代表具體(程式碼)。指定關係和細化關係能確保模型一致性,又使得他們區分不同的抽象層次。

領域模型
領域模型表達了與系統相關的現實世界的不變事實。

設計模型
需要構建的系統不僅會顯示在領域模型中,還會在設計模型中出現。
設計模式由遞迴巢狀的邊界模型和內部模型組成。邊界模型涉及公共介面,內部模型介紹了內部設計。

程式碼模型:系統的原始碼實現。

不同作者提出的模型如何與本書提到的業務模型、領域模型、設計模型(邊界模型和內部模型)和程式碼模型的對應:

設計模型

檢視型別以及檢視型別內容舉例:

檢視型別和質量屬性歸納,也就是設計時關注的一些指標,比如延遲,效率,可伸縮性,安全性,等等:

模型關係

各種關係的列表:

設計模型,實現模型,領域模型(分析模型)

架構風格

架構風格中的元素、關係、約束以及指標,圖:

相關文章