淺談架構:架構的緣起與目標

-     前言     -

在軟件研發這個領域,程序員的終極目標都是想成爲一名合格的架構師。然而夢想很美好,但現實卻很曲折。

在實際工作中,程序員會分很多種,有的擅長編碼實現,有的擅長底層原理,有的擅長邏輯實現等等,在各自的領域都表現不俗、擔當核心,然而,面臨更高層架構設計時,很多優秀的程序員卻折戟沙場,未能完成華麗轉身。

架構的真諦是什麼呢?架構真的如此難把控嗎?難道真的只有天資聰慧、天賦異能的程序員才能駕馭架構嗎?

不要氣餒,平常心,其實人人都是架構師,可能你做的任一一件事已無形中用到了架構。

本篇文章將帶您慢慢走進架構,揭祕架構的真諦。正如,架構不是神祕物,吸取真諦即瞭然。

-     架構的背景     -

如果想要深入理解某一事物的本質,最好的方式就是去追尋這個事物出現的歷史背景和推動因素。所以我們先來梳理一下軟件開發的進化史,探索一下軟件架構出現的歷史背景。

1、機器語言

最早的軟件開發使用的是 “機器語言”,其直接使用二進制碼 0 和 1 來表示機器可以識別的指令和數據。

比如:爲了完成 “將寄存器 BX 的內容送到 AX 中”,機器語言如下:

1000100111011000
面對上面的1&0的字符串,不用多說,程序員心裏肯定會萬馬奔騰吧,更別說輸入錯誤要去定位問題,求程序員的心裏陰影面積?

歸納一下,機器語言的主要問題是三難:

太難寫、太難讀、太難改!

2、彙編語言

爲了解決機器語言編寫、閱讀、修改複雜的問題,彙編語言應運而生。彙編語言又叫 “符號語言”,用助記符代替機器指令的操作碼,用地址符號(Symbol)或標號(Label),代替指令或操作數的地址。

比如:爲了完成 “將寄存器 BX 的內容送到 AX 中”,彙編語言如下:

mov ax,bx

相比機器語言來說,彙編語言就清晰得多了。彙編語言雖然解決了機器語言讀寫複雜的問題,但本質上還是面向機器的,因爲寫彙編語言需要我們精確瞭解計算機底層的知識。

面向機器的語言,帶來的問題就是:

彙編語言需要針對不同 CPU 的彙編指令和結構,代碼編寫多份。

3、高級語言

爲了解決彙編語言的問題,前輩們又設計出了一個 “高級語言”。爲什麼會叫“高級語言” 呢?原因在於這些語言讓程序員不需要關注機器底層的低級結構和指令,只需要關注具體的問題和業務即可。

比如:以 4+6=? 這個加法爲例,如果用 Lisp 語言,只需要簡單一行代碼:

(+ 4 6)

除此以外,通過編譯程序的處理,高級語言可以被編譯爲適合不同 CPU 指令的機器語言。程序員只要寫一次程序,就可以在不同的機器上編譯運行,無須根據不同的機器指令重寫整個程序。

4、兩次軟件危機

第一次軟件危機與結構化程序設計

高級語言的出現,解放了程序員,但好景不長,隨着軟件的規模和複雜度的大大增加,軟件質量低下,質量把控難度高,項目無法如期完成,嚴重超支等現象。例如,1963 年美國的 水手一號火箭發射失敗事故,就是因爲一行 FORTRAN 代碼錯誤導致的。

所以,爲了解決上面的問題,針對性的提出瞭解決方法 “軟件工程”,雖然“軟件工程” 提出之後也曾被視爲軟件領域的銀彈,但後來事實證明,軟件工程同樣無法根除軟件危機,只能在一定程度上緩解軟件危機。

差不多同一時間,“結構化程序設計” 作爲另外一種解決軟件危機的方案被提了出來。結構化程序設計的主要特點是拋棄 goto 語句,採取 “自頂向下、逐步細化、模塊化” 的指導思想。

結構化程序設計本質上還是一種面向過程的設計思想,但通過 “自頂向下、逐步細化、模塊化” 的方法,將軟件的複雜度控制在一定範圍內,從而從整體上降低了軟件開發的複雜度。

第二次軟件危機與面向對象

結構化編程的風靡在一定程度上緩解了軟件危機,然而隨着硬件的快速發展,業務需求越來越複雜,以及編程應用領域越來越廣泛,第二次軟件危機很快就到來了。

第二次軟件危機的根本原因還是 在於軟件生產力遠遠跟不上硬件和業務的發展。

第一次軟件危機的根源在於 軟件的 “邏輯” 變得非常複雜;

第二次軟件危機主要體現在 軟件的 “擴展” 變的非常複雜。

結構化程序設計雖然能夠緩解軟件邏輯的複雜性,但是對於業務變化帶來的軟件擴展卻無能爲力。軟件領域迫切希望找到新的銀彈來解決軟件危機,在這種背景下,面向對象的思想開始流行起來。

雖然面向對象開始也被當做解決軟件危機的銀彈,在一定程度上解決了軟件 “擴展” 帶來的複雜性。但事實證明,和軟件工程、結構化程度設計一樣,面向對象也不是銀彈,而只是一種新的軟件方法而已。

5、軟件架構的產生

與之前的各種新方法或者新理念不同的是,“軟件架構” 出現的背景並不是整個行業都面臨類似相同的問題,“軟件架構” 也不是爲了解決新的軟件危機而產生的,這是怎麼回事呢?

隨着軟件系統規模的增加,計算相關的算法和數據結構不再構成主要的設計問題。當系統由許多部分組成時,整個系統的組織,也就是所說的 “軟件架構”,產生了一系列新的設計問題。比如:

  1. 系統規模龐大,內部耦合嚴重,開發效率低;

  2. 系統耦合嚴重,牽一髮動全身,後續修改和擴展困難;

  3. 系統邏輯複雜,容易出問題,出問題後很難排查和修復;

“軟件架構”的出現有其歷史必然性。第一次軟件危機引出了 “結構化編程”,創造了“模塊” 概念;第二次軟件危機引出了 “面向對象編程”,創造了“對象” 概念;直到 “軟件架構” 的產生,創造了 “組件” 概念。

“模塊”、“對象”和 “組件” 本質上都是對達到一定規模的軟件進行拆分,差別只是在於隨着軟件的複雜度不斷增加,拆分的粒度越來越粗,拆分的層次越來越高。

-     架構指什麼     -

對於技術人員來說,“架構”是一個再常見不過的詞了。當提起 “架構” 這個詞時,如果去深究一下:“架構”到底指什麼?大部分人也許並不一定能夠準確地回答。1000 個人心中可能有 1001 種架構的含義。

那麼如何才能準確的理解架構呢?理解架構首先理解三個有關係而又相似的概念,包括:系統與子系統、模塊與組件、框架與架構。

1、系統與子系統

關於 “系統” 的定義,我們先來看維基百科的定義:

系統泛指由一羣 有關聯 的個體組成,根據某種 規則運作,能完成 個別元件不能單獨完成的工作的羣體。它的意思是 “總體”、“整體” 或“聯盟”。

來提煉下里面的關鍵信息:

  1. 關聯:系統是由一羣有關聯的個體組成的,沒有關聯的個體堆在一起不能成爲一個系統,例如:把一個發動機和一臺 PC 放在一起不能稱之爲一個系統,把發動機、底盤、輪胎、車架組合起來才能成爲一臺汽車。

  2. 規則:系統內的個體需要按照指定的規則運作,而不是單個個體各自爲政。規則規定了系統內個體分工和協作的方式。例如:汽車發動機負責產生動力,然後通過變速器和傳動軸,將動力輸出到輪胎上,從而驅動汽車前進。

  3. 能力:系統能力和個體能力有本質的差別,系統能力也不是個體能力之和,而是產生了新的能力。例如:汽車能夠載重前進,而發動機、變速器、傳動軸、車輪本身都不具備這樣的能力。

再來看下子系統的定義:

子系統也是由一羣有關聯的個體所組成的系統,多半會是更大系統中的一部分。

其實子系統和系統的定義是一樣的,只是觀察的角度有差異,一個系統可能是另外一個更大系統的子系統。

按照這個定義,系統和子系統比較容易理解。以微信爲例來做一個分析:

  1. 微信本身是一個系統,包含聊天、登錄、支付、朋友圈等子系統;

  2. 朋友圈這個系統又包括動態、評論、點贊等子系統;

  3. 評論這個系統可能又包括防刷子系統、審覈子系統、發佈子系統、存儲子系統等;

  4. 評論審覈子系統不再包含業務意義上的子系統,而是包括各個模塊或者組件,這些模塊或者組件本身也是另外一個維度上的系統,例如:MySQL、Redis 等存儲系統,但不是業務子系統。

2、模塊與組件

從邏輯的角度來拆分系統,得到的單元就是 “模塊”;從物理的角度來拆分系統,得到的單元就是“組件”。劃分模塊的主要目的是職責分離;劃分組件的主要目的是單元複用。其實,“組件” 的英文 “component” 也可以翻譯成中文的 “零件” 一詞,“零件”更容易理解一些,“零件”是一個物理的概念,並且具備 “獨立且可替換” 的特點。

3、框架與架構

單純從定義的角度來看,框架關注的是 “規範”,架構關注的是 “結構”。框架的英文是 “Framework”,架構的英文是 “Architecture”。

我們經常會說,比如:“工程採用的是 MVC 架構”、“工程使用的是 SSH 框架” 等。所以,第一句話是站在結構的層面來說明,第二句話是站在規範的層面來說明。

同時,如果是以不同的角度來說明結構,會得出不同的架構描述,比如:

從業務邏輯的角度分解,“學生管理系統” 的架構:

“學生管理系統” 的架構

從物理部署的角度分解,“學生管理系統” 的架構:

“學生管理系統” 的架構

從開發結構的角度分解,“學生管理系統” 的架構:

“學生管理系統” 的架構

4、重新定義架構

軟件架構指軟件系統的頂層結構。

首先,“系統是一羣關聯個體組成”,這些 “個體” 可以是 “子系統”、“模塊”、“組件” 等;架構需要明確系統包含哪些“個體”。

其次,系統中的個體需要 “根據某種規則” 運作,架構需要明確個體運作和協作的規則。

-     總結     -

架構其實就是爲了應對軟件系統複雜度而提出的解決方案。架構關鍵思維即爲判斷與取捨。

正如,在一個有約束的盒子裏去求解或接近最合適的解。這個約束的盒子可能會包含團隊經驗、成本、資源、時間、業務階段等因素摻雜在一起的綜合體,針對這個綜合體,分析出系統架構的複雜度,進行合適的判斷與取捨,從而設計出恰當的架構用在合適的軟件系統中。

作者:猿碼架構

來源:https://www.jianshu.com/p/312af3e8b94a

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/qE9M8XXFH0iM5DNsQpG5Ow