本文摘自資深技術(shù)專家李運(yùn)華在極客時(shí)間 App/ 小程序上開設(shè)的 50 期付費(fèi)專欄《從 0 開始學(xué)架構(gòu)》。更多架構(gòu)文章,請戳此查看目錄, 新用戶注冊立減 30 元,支持微信支付 。
對于技術(shù)人員來說,“架構(gòu)”是一個(gè)再常見不過的詞了。我們會(huì)對新員工培訓(xùn)整個(gè)系統(tǒng)的架構(gòu),參加架構(gòu)設(shè)計(jì)評審,學(xué)習(xí)業(yè)界開源系統(tǒng)(例如,MySQL、Hadoop)的架構(gòu),研究大公司的架構(gòu)實(shí)現(xiàn)(例如,微信架構(gòu)、淘寶架構(gòu))……雖然“架構(gòu)”這個(gè)詞常見,但如果深究一下 [strong_begin]“架構(gòu)”到底指什么 [strong_end],大部分人也許并不一定能夠準(zhǔn)確地回答。例如:
??? 1. 架構(gòu)和框架是什么關(guān)系?有什么區(qū)別?
??? 2. Linux 有架構(gòu),MySQL 有架構(gòu),JVM 也有架構(gòu),使用 Java 開發(fā)、MySQL 存儲(chǔ)、跑在 Linux 上的業(yè)務(wù)系統(tǒng)也有架構(gòu),應(yīng)該關(guān)注哪個(gè)架構(gòu)呢?
??? 3..微信有架構(gòu),微信的登錄系統(tǒng)也有架構(gòu),微信的支付系統(tǒng)也有架構(gòu),當(dāng)我們談微信架構(gòu)時(shí),到底是在談什么架構(gòu)?
要想準(zhǔn)確地回答這幾個(gè)問題,關(guān)鍵在于梳理幾個(gè)有關(guān)系而又相似的概念,包括:系統(tǒng)與子系統(tǒng)、模塊與組件、框架與架構(gòu)。
系統(tǒng)與子系統(tǒng)
我們先來看維基百科定義的“系統(tǒng)”。
系統(tǒng)泛指由一群有關(guān)聯(lián)的個(gè)體組成,根據(jù)某種規(guī)則運(yùn)作,能完成個(gè)別元件不能單獨(dú)完成的工作的群體。它的意思是“總體”“整體”或“聯(lián)盟”。
我來提煉一下里面的關(guān)鍵內(nèi)容:
關(guān)聯(lián):系統(tǒng)是由一群有關(guān)聯(lián)的個(gè)體組成的,沒有關(guān)聯(lián)的個(gè)體堆在一起不能成為一個(gè)系統(tǒng)。例如,把一個(gè)發(fā)動(dòng)機(jī)和一臺(tái) PC 放在一起不能稱之為一個(gè)系統(tǒng),把發(fā)動(dòng)機(jī)、底盤、輪胎、車架組合起來才能成為一臺(tái)汽車。
規(guī)則:系統(tǒng)內(nèi)的個(gè)體需要按照指定的規(guī)則運(yùn)作,而不是單個(gè)個(gè)體各自為政。規(guī)則規(guī)定了系統(tǒng)內(nèi)個(gè)體分工和協(xié)作的方式。例如,汽車發(fā)動(dòng)機(jī)負(fù)責(zé)產(chǎn)生動(dòng)力,然后通過變速器和傳動(dòng)軸,將動(dòng)力輸出到車輪上,從而驅(qū)動(dòng)汽車前進(jìn)。
能力:系統(tǒng)能力與個(gè)體能力有本質(zhì)的差別,系統(tǒng)能力不是個(gè)體能力之和,而是產(chǎn)生了新的能力。例如,汽車能夠載重前進(jìn),而發(fā)動(dòng)機(jī)、變速器、傳動(dòng)軸、車輪本身都不具備這樣的能力。
我們再來看子系統(tǒng)的定義。
子系統(tǒng)也是由一群有關(guān)聯(lián)的個(gè)體所組成的系統(tǒng),多半會(huì)是更大系統(tǒng)中的一部分。
其實(shí)子系統(tǒng)的定義和系統(tǒng)定義是一樣的,只是觀察的角度有差異,一個(gè)系統(tǒng)可能是另外一個(gè)更大系統(tǒng)的子系統(tǒng)。
按照這個(gè)定義,系統(tǒng)和子系統(tǒng)比較容易理解。我們以微信為例來做一個(gè)分析。
1. 微信本身是一個(gè)系統(tǒng),包含聊天、登錄、支付、朋友圈等子系統(tǒng)。
2. 朋友圈這個(gè)系統(tǒng)又包括動(dòng)態(tài)、評論、點(diǎn)贊等子系統(tǒng)。
3. 評論這個(gè)系統(tǒng)可能又包括防刷子系統(tǒng)、審核子系統(tǒng)、發(fā)布子系統(tǒng)、存儲(chǔ)子系統(tǒng)。
4. 評論審核子系統(tǒng)不再包含業(yè)務(wù)意義上的子系統(tǒng),而是包括各個(gè)模塊或者組件,這些模塊或者組件本身也是另外一個(gè)維度上的系統(tǒng)。例如,MySQL、Redis 等是存儲(chǔ)系統(tǒng),但不是業(yè)務(wù)子系統(tǒng)。
模塊與組件
模塊和組件兩個(gè)概念在實(shí)際工作中很容易混淆,我們經(jīng)常能夠聽到類似這樣的說法:
1. MySQL 模塊主要負(fù)責(zé)存儲(chǔ)數(shù)據(jù),而 ElasticSearch 模塊主要負(fù)責(zé)數(shù)據(jù)搜索。
2. 我們有安全加密組件、有審核組件。
3. App 的下載模塊使用了第三方的組件。
造成這種現(xiàn)象的主要原因是,模塊與組件的定義并不好理解,也不能很好地進(jìn)行區(qū)分。我們來看看這兩者在維基百科上的定義。
軟件模塊(Module)是一套一致而互相有緊密關(guān)連的軟件組織。它分別包含了程序和數(shù)據(jù)結(jié)構(gòu)兩部分。現(xiàn)代軟件開發(fā)往往利用模塊作為合成的單位。模塊的接口表達(dá)了由該模塊提供的功能和調(diào)用它時(shí)所需的元素。模塊是可能分開被編寫的單位。這使它們可再用和允許人員同時(shí)協(xié)作、編寫及研究不同的模塊。
軟件組件定義為自包含的、可編程的、可重用的、與語言無關(guān)的軟件單元,軟件組件可以很容易被用于組裝應(yīng)用程序中。
可能你看完這兩個(gè)定義后一頭霧水,還是不知道這兩者有什么區(qū)別。造成這種現(xiàn)象的根本原因是,模塊和組件都是系統(tǒng)的組成部分,只是從不同的角度拆分系統(tǒng)而已。
從邏輯的角度來拆分系統(tǒng)后,得到的單元就是“模塊”;從物理的角度來拆分系統(tǒng)后,得到的單元就是“組件”。劃分模塊的主要目的是職責(zé)分離;劃分組件的主要目的是單元復(fù)用。其實(shí),“組件”的英文 component 也可翻譯成中文的“零件”一詞,“零件”更容易理解一些,“零件”是一個(gè)物理的概念,并且具備“獨(dú)立且可替換”的特點(diǎn)。
我以一個(gè)最簡單的網(wǎng)站系統(tǒng)來為例。假設(shè)我們要做一個(gè)學(xué)生信息管理系統(tǒng),這個(gè)系統(tǒng)從邏輯的角度來拆分,可以分為“登錄注冊模塊”“個(gè)人信息模塊”“個(gè)人成績模塊”;從物理的角度來拆分,可以拆分為 Nginx、Web 服務(wù)器、MySQL。
框架與架構(gòu)
框架是和架構(gòu)比較相似的概念,且兩者有較強(qiáng)的關(guān)聯(lián)關(guān)系,所以在實(shí)際工作中,這兩個(gè)概念有時(shí)我們?nèi)菀追植磺宄?。參考維基百科上框架與架構(gòu)的定義,我來解釋兩者的區(qū)別。
軟件框架(Software framework)通常指的是為了實(shí)現(xiàn)某個(gè)業(yè)界標(biāo)準(zhǔn)或完成特定基本任務(wù)的軟件組件規(guī)范,也指為了實(shí)現(xiàn)某個(gè)軟件組件規(guī)范時(shí),提供規(guī)范所要求之基礎(chǔ)功能的軟件產(chǎn)品。
我來提煉一下其中關(guān)鍵部分:
1. 框架是組件規(guī)范:例如,MVC 就是一種最常見的開發(fā)規(guī)范,類似的還有 MVP、MVVM、J2EE 等框架。
2. 框架提供基礎(chǔ)功能的產(chǎn)品:例如,Spring MVC 是 MVC 的開發(fā)框架,除了滿足 MVC 的規(guī)范,Spring 提供了很多基礎(chǔ)功能來幫助我們實(shí)現(xiàn)功能,包括注解(@Controller 等)、Spring Security、Spring JPA 等很多基礎(chǔ)功能。
軟件架構(gòu)指軟件系統(tǒng)的“基礎(chǔ)結(jié)構(gòu)”,創(chuàng)造這些基礎(chǔ)結(jié)構(gòu)的準(zhǔn)則,以及對這些結(jié)構(gòu)的描述。
單純從定義的角度來看,框架和架構(gòu)的區(qū)別還是比較明顯的,框架關(guān)注的是“規(guī)范”,架構(gòu)關(guān)注的是“結(jié)構(gòu)”??蚣艿挠⑽氖?Framework,架構(gòu)的英文是 Architecture。Spring MVC 的英文文檔標(biāo)題就是“Web MVC framework”。
雖然如此,在實(shí)際工作中我們卻經(jīng)常碰到一些似是而非的說法。例如,“我們的系統(tǒng)是 MVC 架構(gòu)”“我們需要將 android app 重構(gòu)為 MVP 架構(gòu)”“我們的系統(tǒng)基于 SSH 框架開發(fā)”“我們是 SSH 的架構(gòu)”“XX 系統(tǒng)是基于 Spring MVC 框架開發(fā),標(biāo)準(zhǔn)的 MVC 架構(gòu)”……
究竟什么說法是對的,什么說法是錯(cuò)的呢?
其實(shí)這些說法都是對的,造成這種現(xiàn)象的根本原因隱藏于架構(gòu)的定義中,關(guān)鍵就是“基礎(chǔ)結(jié)構(gòu)”這個(gè)概念并沒有明確說是從什么角度來分解的。采用不同的角度或者維度,可以將系統(tǒng)劃分為不同的結(jié)構(gòu),其實(shí)我在“模塊與組件”中的“學(xué)生管理系統(tǒng)”示例已經(jīng)包含了這點(diǎn)。
從業(yè)務(wù)邏輯的角度分解,“學(xué)生管理系統(tǒng)”的架構(gòu)是:
從物理部署的角度分解,“學(xué)生管理系統(tǒng)”的架構(gòu)是:
從開發(fā)規(guī)范的角度分解,“學(xué)生管理系統(tǒng)”可以采用標(biāo)準(zhǔn)的 MVC 框架來開發(fā),因此架構(gòu)又變成了 MVC 架構(gòu):
這些“架構(gòu)”,都是“學(xué)生管理系統(tǒng)”正確的架構(gòu),只是從不同的角度來分解而已,這也是 IBM 的 RUP 將軟件架構(gòu)視圖分為著名的“4+1 視圖”的原因。
重新定義架構(gòu)
參考維基百科的定義,我將架構(gòu)重新定義為:軟件架構(gòu)指軟件系統(tǒng)的頂層結(jié)構(gòu)。
這個(gè)定義看似很簡單,但包含的信息很豐富,基本上把系統(tǒng)、子系統(tǒng)、模塊、組件、架構(gòu)等概念都串起來了,我來詳細(xì)解釋一下。
首先,“系統(tǒng)是一群關(guān)聯(lián)個(gè)體組成”,這些“個(gè)體”可以是“子系統(tǒng)”“模塊”“組件”等;架構(gòu)需要明確系統(tǒng)包含哪些“個(gè)體”。
其次,系統(tǒng)中的個(gè)體需要“根據(jù)某種規(guī)則”運(yùn)作,架構(gòu)需要明確個(gè)體運(yùn)作和協(xié)作的規(guī)則。
第三,維基百科定義的架構(gòu)用到了“基礎(chǔ)結(jié)構(gòu)”這個(gè)說法,我改為“頂層結(jié)構(gòu)”,可以更好地區(qū)分系統(tǒng)和子系統(tǒng),避免將系統(tǒng)架構(gòu)和子系統(tǒng)架構(gòu)混淆在一起導(dǎo)致架構(gòu)層次混亂。
小結(jié)
今天我為你梳理了與架構(gòu)有關(guān)的幾個(gè)容易混淆的概念,包括系統(tǒng)與子系統(tǒng)、模塊與組件、框架與架構(gòu),解釋了架構(gòu)的定義,希望對你有所幫助。
這就是今天的全部內(nèi)容,留一道思考題給你吧。你原來理解的架構(gòu)是如何定義的?對比我今天講的架構(gòu)定義,你覺得差異在哪里?
歡迎你把答案寫到留言區(qū),和我一起討論。相信經(jīng)過深度思考的回答,也會(huì)讓你對知識(shí)的理解更加深刻。