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


簡介

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

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

一、什么是軟件架構?

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

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

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

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

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

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

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

架構是設計的宏觀部分。

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

二、軟件架構為什么重要

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

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

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

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

三、架構何時變得重要

有以下幾個方面

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

翻譯成 解,真不好理解

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

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

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

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

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

企業架構師和應用架構師

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

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

架構設計的方式有哪些

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

四、風險驅動模型

4.1 什么是風險驅動模型:

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

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

4.2 項目領域典型的風險

如下圖:
project-risk

4.3 識別風險以及風險決策

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

  • 典型風險
    在某一領域工作一段時間后,你就會注意到一些典型風險,他們對於該領域大多數項目而言都是很常見的。
    所以,我們需要找到它。

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

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

我的舉例:比如,訪問量大了之后,數據庫可能抗不住,你會想到增加一層緩存來降低對數據庫的直接訪問。

從分析到解決方案。

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

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

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

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

做出技術合理決策公式

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

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

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

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

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

放眼望去,總是很難判斷運用哪些技術才是合適的。每種技術都有其價值,但卻未必是項目最需要的價值。

我理解:這就是項目技術選型難點之一。技術選擇多,會“眼花繚亂”。

五、技術選型指導原則

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

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

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

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

“該系統是否一直符合該框架的應用程序編程接口?” 這就是需要證明的問題。盡管可以做多種測試,但,仍然會有某些情況被忽略了。

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

六、如何把握設計與架構的度

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

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

6.1 演進式設計

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

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

6.2 計划式設計

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

6.3 最小計划式設計

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

在計划式設計與演進式設計之間取得平衡是可能的。
一種方法是做一些初步的計划式設計,確保架構可以處理一些最大風險。在初始計划式設計完成后,未來的需求變化往往通過局部設計去處理,或采用演技式設計,前提是重構、測試驅動設計和持續集成等實踐在項目中已經開展起來。

6.4 理解過程變化

幾種開發模型的比較:

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

6.5 風險驅動模型缺點

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

七、建模

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

7.1 規模與復雜度

規模越大,復雜度越高,越需要抽象進行建模。

模型為解決問題提供了洞察力和解決手段。它是解決復雜問題的一種方式。

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

模型忽略了細節

站在巨人肩膀上,以前的“巨人”不僅為我們提供了可見的編譯器和數據庫,還提供了一套抽象的編程思維理論。一部分抽象概念已經植根於編程語言中--函數、類、模塊等。其余則包括組件、端口和連接器。

7.2 領域模型、設計模型和代碼模型

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

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

設計模型
需要構建的系統不僅會顯示在領域模型中,還會在設計模型中體現。

設計模式由遞歸嵌套的邊界模型和內部模型組成。邊界模型涉及公共接口,內部模型介紹了內部設計。

代碼模型:系統的源代碼實現。

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

八、設計模型

視圖類型以及視圖類型內容舉例:

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

九、模型關系

各種關系的列表:

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

十、架構風格

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM