不論是開發人員還是架構師,我們都一直在跟軟體系統打交道,架構是在工作中出現最頻繁的術語之一。那麼,到底什麼是架構?你可能有自己的答案,也有可能沒有答案。對「架構」的理解需要我們不斷在實踐中思考、歸納、演繹,形成自己的認知。
定義 」架構是什麼「 是件非常困難的事情,不同的組織對於軟體架構有不同的定義,每個人心中也有自身對於系統架構定義的認知。就好比我們無法百分之百表述模型而只能產出模型不同維度的檢視,對架構進行完備的定義是不可能的。
「道可道,非常道。名可名,非常名」。
行業內不同的組織和個人從不同的視角對 「什麼是架構」 進行了定義或闡述。
IEEE 關於架構的定義
the fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution --ANSI/IEEE
將系統架構定義為:架構是系統組織結構 + 元件及聯絡(元件間以及元件和環境之間) + 原則的組合。通過圖形化的形式表述該架構定義如下圖所示,這是一個非常簡潔、概念清晰的定義,其言簡意賅的表達了架構的幾個核心要素:
大師 Martin Fowler對於架構的定義有著更加簡潔的抽象,Martin Fowler 認為軟體架構是:重要並且難以改變的決策。架構設計是關於權衡的藝術,架構設計過程中充滿了各種各樣的決策,這些決策也終將反應系統架構。
Software Architecture = Important and hard to change decisions --Martin Fowler
而Ralph Johnson則對架構有更加 「泛化」 的定義:軟體架構就是重要的東西,不論它是什麼!
The software architecutre is the important stuff ! Whatever it is ! --Ralph Johnson
以上的定義從高層抽象視角對什麼是架構給予了自己的回答,相比之下,Neil Ford 從架構組成元素入手,從更偏向實踐的角度對架構進行了闡述。核心思想是軟體系統的架構包括以下組合元素:
結構
結構是系統架構的重要組成部分,其從宏觀上表述了系統的結構組成。架構設計的核心任務之一是為系統選擇合適的架構風格。比如,架構師基於上下文的權衡,可以選擇模組化單體架構風格,也可以選擇微服務架構風格。
架構屬性
架構屬性亦稱質量屬性,或非功能屬性,通常表示系統需要具備或滿足的某種 「能力」,比如高效能、可延伸性、彈性、伸縮性、容錯性、可測試性、可維護性等等。架構設計的目標需要關注系統需要滿足的架構屬性,架構最終要體現對架構屬性支援的相關架構決策。架構屬性眾多,系統需要關注的是這些架構屬性的子集,具體的某次特定的架構設計所需要關注的架構屬性需要依據問題域的上下文而具體分析。同時,不同的架構屬性間可能存在衝突,這種情況同樣需要架構師的權衡和決策。
架構決策
架構決策是系統架構設計過程中對解決方案的選擇,其描述了系統必須遵循的規則。架構決策隨著權衡分析而自然存在,其是系統架構設計的重要維度之一。並不是所有的決策都是架構決策,架構決策應該關注對系統有重要影響的部分。比如對架構風格的選擇對系統存在重要影響,其改變的成本較高,理當屬於架構決策的範疇。比較典型架構決策包括但不限於:
注:架構決策建議以輕量級的檔案化形式進行記錄,參考文章 《輕量級的架構決策記錄機制》一文
設計原則
設計原則與架構決策不同,其本質區別是:設計原則是一種指導,而非強制的規則。架構決策需要遵守,設計原則提供參考性指引。
比如,設計原則可能是:在可能的情況下,跨系統間的通訊儘可能使用非同步訊息機制以提高效能和降低耦合。
以上對架構的定義各有特點:
我個人更傾向於Ralph Johnson 對於架構的抽象化定義,簡單卻不失對架構本質的闡述,這也是我在工作中判斷架構邊界的準則之一。
如果你是團隊的架構師,你是否有以下困惑:
如果你是團隊的核心開發人員,你是否 「抱怨」 過:
很多架構師自身對架構和設計的邊界缺乏深入認知,相比於對架構邊界的縮小,更多時候會出現架構設計邊界放大的情況:
架構師把架構設計當作詳細的技術方案設計,牢牢把控系統實現的所有細節,產出大量的設計檔案,然後交由核心開發人員做程式碼實現的執行工作。
這種現象會導致如下問題:
以上問題的根源是什麼?不能明確架構設計的邊界!
判斷架構邊界的前提之一是:明確架構和設計的關係!
所有的架構都是設計,但設計不一定是架構!
從架構的定義看架構設計的邊界,選取兩個視角:
所以,架構設計應該涵蓋系統中重要的東西,這些 「重要的東西」 可能是:
架構設計涵蓋了系統所需的重要的架構決策,從宏觀層面對系統實現予以指引。而詳細的設計則為具體的開發實現提供指導,比如,詳細的E-R圖設計、具體的程式碼級別的模式選擇、某個元件的具體實現等等。
架構不是一成不變,需要持續演進,而實現相關的設計也可能在專案進行中持續變化,因此,二者不能完全割裂,而是需要在實現過程中進行雙向反饋:
在進行架構邊界判定時要注意一個至關重要的因子:上下文!!!以上的判斷準則必須要給定的上下文中才有價值。
比如:實現過程中大家經常會適用一些設計模式,例如策略模式。那麼,這種設計模式的選擇是屬於架構設計還是詳細的實現設計?答案就是:It depends!!! 具體情況,具體分析。
如果當前上下文,我們非常關注系統的擴充套件性,該架構屬性是我們高優先順序的架構屬性,那麼,核心模組的策略模式的應用可以看作是架構設計的範疇。而如果上下文中擴充套件性不是我們關注的高優先順序的架構屬性,相比我們更關注效能,那麼,這種程式碼級的設計模式選擇應該屬於架構設計的範疇之外了,而需要劃分到實現設計層面,交由核心開發自主決定。
架構模式和架構風格是極容易混淆的兩個概念,很多開發人員將其理解為同一事物,而實際上二者有本質區別。
二者概念不同,並不存在衝突,其聯絡如下圖所示:
比較典型的例子是CQRS:CQRS本身是一種模式,將命令和查詢的職責在不同維度進行分離。該模式我們可以在單體架構風格中使用,也可以在微服務架構風格中使用,當然也可以在SOA架構風格中使用。
至於 「為什麼要做架構設計」 也是一個古老且頻繁出現的問題,有太多的文章闡述為社麼要架構設計:有的宏觀,有的具體,有的「務實」,有的「務虛」。我把這個問題作為一個獨立章節闡述,並不是想進行大篇幅的論述,只是想突出它的重要性,這個問題值得耗費一些精力去深入理解其背後的原因。但,在此不做展開過多說明,通過一句話來進行概括:
之所以要進行架構設計,是因為:重要 !
作為開發人員,更加關注知識的深度,以便有足夠的知識儲備滿足工作需要。開發人員在職業生涯的早期,應該關注於自身知識儲備的增長,並保持技術深度。
作為架構師,之所以技術的廣度比深度更重要,是因為架構師的重要職責之一是進行架構決策。系統架構設計是關於權衡的藝術,在特定的問題域上下文下,架構師需要在諸多可行的解決方案間進行權衡和決策,這也對其技術廣度提出了要求。開發人員成長為架構師,應該更加關注知識的廣度,並在幾個特定領域深耕,以便有足夠的知識支撐架構決策。
雖然開發人員和架構師在知識域的關注點上存在差異,但在認知層面都可以統一到Bloom認知層次模型。該模型將認知層次劃分為逐步遞進的六個層次:
不論是架構師還是開發人員,Bloom認知層次模型都適用。通過不斷的學習擴充套件自身的知識體系,在識記、理解和應用的同時,要持續的培養分析、評估和創造的能力,逐步向高層次的認知水平提升。
但需要注意的是:知識不等於認知,避免陷入知識學習的陷阱。知識是無限的,沒有人能夠以有限的精力去學習無限的知識。不論是開發人員還是架構師,又或者其他角色,不應該只將精力投入在知識邊界的擴充,而應該注重從知識到認知提升的轉變。
吾生也有涯,而知也無涯。以有涯隨無涯,殆矣!已而為知者,殆而已矣! ----《莊子》
格物以致知,對錶象不斷的歸納、演繹直至事物的本象,探尋事物背後的規律,建立更高層的認知。這種認知層次由下及上的躍升有兩種方式:
為學日益,為道日損。損之又損,以⾄於⽆為。⽆為⽽⽆不為。 --《道德經》
對架構定義的探討實際上是一種樸素的 「格物」 的過程,每個人都應該尋找自己的答案。跳脫對架構定義探討的視野,大家的工作和學習何嘗不是如此呢 ?!大道至簡,殊途同歸,格物致知,與君共勉!
作者:倪新明