一、前言
系統(tǒng)架構(gòu)思想是軟件開發(fā)工程師的工作必備知識(shí)。大到大型互聯(lián)網(wǎng)應(yīng)用系統(tǒng)的設(shè)計(jì),小到一個(gè)軟件功能函數(shù)的設(shè)計(jì),都需要擁有架構(gòu)設(shè)計(jì)思想。軟件架構(gòu)分層就是架構(gòu)設(shè)計(jì)中的一個(gè)子領(lǐng)域,更著重強(qiáng)調(diào)軟件的分層概念。 本篇文章就帶大家簡(jiǎn)單的了解一下軟件架構(gòu)的分層,學(xué)習(xí)完畢,你就會(huì)明白,為什么系統(tǒng)要分層,架構(gòu)分層可以帶來什么好處。
二、軟件架構(gòu)分層的發(fā)展背景
計(jì)算機(jī)編程在“上古時(shí)代”開始時(shí),是用二進(jìn)制來編程,后面逐漸發(fā)展成熟。到了20 世紀(jì) 60 年代第一次軟件危機(jī)時(shí),引出了“結(jié)構(gòu)化編程”,并創(chuàng)造了“模塊”概念;20 世紀(jì) 80 年代第二次軟件危機(jī)引出了“面向?qū)ο缶幊獭?,?chuàng)造了“對(duì)象”概念;到了 20 世紀(jì) 90 年代, 隨著軟件規(guī)模的不斷增大,以下問題就開始顯現(xiàn)。
系統(tǒng)規(guī)模龐大,內(nèi)部耦合嚴(yán)重,開發(fā)效率低;
系統(tǒng)耦合嚴(yán)重,牽一發(fā)動(dòng)全身,后續(xù)修改和擴(kuò)展困難;
系統(tǒng)邏輯復(fù)雜,容易出問題,出問題后很難排查和修復(fù)。
于是在Rational 和 Microsoft 內(nèi)部,軟件架構(gòu)的概念開始越來越流行了。“組件”概念隨著軟件架構(gòu)的流行也逐漸清晰。 我們可以看到,“模塊”“對(duì)象”“組件”本質(zhì)上都是對(duì)達(dá)到一定規(guī)模的軟件進(jìn)行拆分,差別只是在于隨著軟件的復(fù)雜度不斷增加,拆分的粒度越來越粗,拆分的層次越來越高。 隨著90年代互聯(lián)網(wǎng)的迅速崛起,軟件架構(gòu)分層也隨著軟件架構(gòu)的興起而逐步興起。
三、軟件分層的概念
軟件架構(gòu)分層就是將軟件模塊按照水平切分的方式分成多個(gè)層,一個(gè)系統(tǒng)由多層組成,每層由多個(gè)模塊組成。每層有自己獨(dú)立的職責(zé),為上一層提供服務(wù),使用下一層的服務(wù),每層只能看到處自己相臨的層。多個(gè)層次協(xié)同提供完整的功能。通過分層結(jié)構(gòu),可以將大的問題分解為若干個(gè)漸進(jìn)的小問題來解決,可以隱蔽問題的復(fù)雜度。修改某一層,最多影響其相鄰的兩層(通常只能影響上層)。 這里引申到層間隔離的概念。分層架構(gòu)中的每一層可以是封閉的或者開放的,封閉意味著當(dāng)一個(gè)請(qǐng)求自頂向下在層間傳遞時(shí),它不能跳過任意的一層。所謂的層間隔離,旨在降低一個(gè)層次上的變化對(duì)其他層次的組件的影響。簡(jiǎn)單來說,就是每個(gè)層次對(duì)其他層次的功能知道的越少越好。但是在某些的場(chǎng)景,將特定的層次置為開放的狀態(tài)也不失為一件好事。還有某些不想被其它層看到的代碼也可以通過層間隔離的手段來實(shí)現(xiàn)。
四、軟件分層的特點(diǎn)
分層設(shè)計(jì)的本質(zhì)其實(shí)就是將復(fù)雜問題簡(jiǎn)單化,基于單一職責(zé)原則讓每層代碼各司其職,基于“高內(nèi)聚,低耦合”的設(shè)計(jì)思想實(shí)現(xiàn)相關(guān)層對(duì)象之間的交互。從而,提升代碼的可維護(hù)性和可擴(kuò)展性。系統(tǒng)架構(gòu)分層之后,一般要具有以下特點(diǎn):
高內(nèi)聚:分層設(shè)計(jì)可以簡(jiǎn)化系統(tǒng)設(shè)計(jì),讓不同層專注做本層相關(guān)的事,同時(shí)更利于系統(tǒng)開發(fā)工作的分配,讓“專業(yè)的人做專業(yè)的事”。這也體現(xiàn)了軟件設(shè)計(jì)思想的“單一職責(zé)原則”;
低耦合:層與層之間通過接口或API來交互,依賴方不用知道被依賴方的細(xì)節(jié)。這樣即使某一層發(fā)生較大的變化,其它層也不需要做較多改動(dòng)就可以適配。軟件設(shè)計(jì)思想的“迪米特法則”在這里得到了體現(xiàn);
復(fù)用/可移植性:分層之后可以做到代碼或功能的復(fù)用;
擴(kuò)展性/易裁剪:分層架構(gòu)可以讓代碼更容易橫向擴(kuò)展或者裁剪。這里體現(xiàn)了軟件設(shè)計(jì)思想的“開閉原則”。
任何事物都不可能是盡善盡美的,分層架構(gòu)雖有優(yōu)勢(shì)也會(huì)有缺陷,比如分層可能會(huì)增加代碼量。通過層層調(diào)用會(huì)降低了代碼效率。 下面列用幾種常見的分層架構(gòu)來說明以上作用。
五、常見的分層架構(gòu)
TCP/IP協(xié)議的四層架構(gòu):它把網(wǎng)絡(luò)簡(jiǎn)化成了四層,即鏈路層、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層。每一層各司其職又互相幫助,網(wǎng)絡(luò)層負(fù)責(zé)端到端的尋址和建立連接,傳輸層負(fù)責(zé)端到端的數(shù)據(jù)傳輸?shù)?,同時(shí)相鄰兩層還會(huì)有數(shù)據(jù)的交互。這樣可以隔離關(guān)注點(diǎn),讓不同的層專注做不同的事情。
Linux文件系統(tǒng)分層:從下圖你可以清晰地看出文件系統(tǒng)的層次。在文件系統(tǒng)的最上層是虛擬文件系統(tǒng)(VFS),用來屏蔽不同的文件系統(tǒng)之間的差異,提供統(tǒng)一的系統(tǒng)調(diào)用接口。虛擬文件系統(tǒng)的下層是 Ext3、Ext4 等各種文件系統(tǒng),再向下是為了屏蔽不同硬件設(shè)備的實(shí)現(xiàn)細(xì)節(jié),我們抽象出來的單獨(dú)的一層——通用塊設(shè)備層,然后就是不同類型的磁盤了。
我們可以看到,某些層次負(fù)責(zé)的是對(duì)下層不同實(shí)現(xiàn)的抽象,從而對(duì)上層屏蔽實(shí)現(xiàn)細(xì)節(jié)。比方說VFS 對(duì)上層(系統(tǒng)調(diào)用層)來說提供了統(tǒng)一的調(diào)用接口,同時(shí)對(duì)下層中不同的文件系統(tǒng)規(guī)約了實(shí)現(xiàn)模型,當(dāng)新增一種文件系統(tǒng)實(shí)現(xiàn)的時(shí)候,只需要按照這種模型來設(shè)計(jì),就可以無縫插入到 Linux 文件系統(tǒng)中。
網(wǎng)絡(luò)服務(wù)架構(gòu)分層:下圖是目前常見的網(wǎng)絡(luò)服務(wù)架構(gòu),分為部署的硬件環(huán)境、操作系統(tǒng)、所需的中間件、承載業(yè)務(wù)的應(yīng)用程序以及軟件接入層等。不同的層次也產(chǎn)生了對(duì)應(yīng)在職位,比如運(yùn)維工程師、中間件工程師、產(chǎn)品經(jīng)理、開發(fā)工程師、測(cè)試工程師等工種。而我們?cè)趯?shí)踐過程中,接觸最多,使用最多的分層要屬應(yīng)用軟件層了,其次是中間件層。
嵌入式軟件架構(gòu)分層:在嵌入式系統(tǒng)中,軟件的分層同樣很重要。嵌入式系統(tǒng)中的核心是芯片,以及圍繞著芯片展開的一系列硬件電路,但是不同的嵌入式項(xiàng)目之間硬件差異很大,為了讓硬件能夠按指定的方式工作,就需要為相應(yīng)的硬件“量身定制”硬件層代碼。雖然硬件之間有差異,但還是存在一些共同點(diǎn),比如驅(qū)動(dòng)LCD工作,外接幾個(gè)IO口來支持按鍵或控制小燈的開關(guān)等功能。為了屏蔽硬件底層的差異,同時(shí)提供統(tǒng)一的功能硬件接口,于是硬件抽象層就產(chǎn)生了。業(yè)務(wù)代碼則實(shí)現(xiàn)嵌入式系統(tǒng)指定的業(yè)務(wù)功能,定義了系統(tǒng)在什么條件下做什么反應(yīng),或者定期執(zhí)行一些什么動(dòng)作。為了讓業(yè)務(wù)代碼開發(fā)更方便,不重復(fù)“造輪子”,需要收集很多現(xiàn)成的“輪子”,比較典型的“輪子”就是操作系統(tǒng),它是眾多“輪子”的集合,給應(yīng)用程序提供了多任務(wù),中斷,任務(wù)間通信等功能,這一層我姑且叫它“功能層”。
六、怎么分
在做架構(gòu)分層時(shí),開發(fā)團(tuán)隊(duì)需要做到以下幾點(diǎn):
1. 讓團(tuán)隊(duì)深入理解軟件分層的義意,清晰軟件分層的目的
分層的作用在上面已經(jīng)列出來,只有充分認(rèn)識(shí)到軟件分層帶來的好處,才會(huì)有動(dòng)力去設(shè)計(jì)與實(shí)現(xiàn)分層。
2. 合理設(shè)計(jì)分層,清晰定義每層的職責(zé)
基于“高內(nèi)聚,低耦合”的設(shè)計(jì)思想,定義每層的職責(zé),每層再設(shè)計(jì)不同的模塊。層次數(shù)量可以根據(jù)實(shí)際需要來調(diào)整。建議最多不要超過7層,3到4層最佳。
3.避免掉進(jìn)sinkhole反模式的陷阱
所謂sinkhole反模式指的是請(qǐng)求只是簡(jiǎn)單地路過各個(gè)層次,并沒有做一些業(yè)務(wù)處理。 比如,表現(xiàn)層接收到一個(gè)獲取基本用戶數(shù)據(jù)(姓名、地址等)的請(qǐng)求后將它傳遞到業(yè)務(wù)層;然而,業(yè)務(wù)層并沒有做任何的業(yè)務(wù)處理,直接將請(qǐng)求傳遞到持久層;持久層也僅僅是構(gòu)造了一個(gè)簡(jiǎn)單的SQL語句,向數(shù)據(jù)層查詢用戶數(shù)據(jù);最后,數(shù)據(jù)按照原路返回到表現(xiàn)層,中途沒有經(jīng)過任何的數(shù)據(jù)匯聚、轉(zhuǎn)換等操作。sinkhole反模式會(huì)導(dǎo)致很多不必要的對(duì)象實(shí)例化開銷,從而增大了系統(tǒng)的內(nèi)存消耗,并且影響了性能。 利用80-20原則可以幫助確定架構(gòu)是否陷入sinkhole反模式。大概有百分之二十的請(qǐng)求僅僅是做簡(jiǎn)單的穿透,百分之八十的請(qǐng)求會(huì)做一些業(yè)務(wù)邏輯操作是正常的情況。然而,如果這個(gè)比例反過來,大部分的請(qǐng)求都是僅僅穿過層,不做邏輯操作,架構(gòu)就陷入了sinkhole反模式,可以對(duì)一些架構(gòu)層進(jìn)行開放或者減少層級(jí)關(guān)系。
4. 通過技術(shù)手段守護(hù)架構(gòu)
當(dāng)定義清楚了分層架構(gòu),必然也要有守護(hù)架構(gòu)的一些原則,在《演進(jìn)式架構(gòu)》中推薦盡早確定系統(tǒng)的適應(yīng)度函數(shù),并定期的審查,根據(jù)業(yè)務(wù)和技術(shù)的需求修改當(dāng)前的適應(yīng)度函數(shù)或增加新的適應(yīng)度函數(shù),以保證架構(gòu)能夠按照設(shè)計(jì)的方向發(fā)展。 在java進(jìn)程內(nèi),有一些自動(dòng)化工具可以通過測(cè)試的方式來驗(yàn)證代碼的架構(gòu)是否遵循了預(yù)先設(shè)計(jì)的原則(如ArchUnit),可以高效的幫團(tuán)隊(duì)識(shí)別出在開發(fā)過程中破壞原則的代碼實(shí)現(xiàn)。
5.提升團(tuán)隊(duì)整體認(rèn)知水平和協(xié)作水平
在團(tuán)隊(duì)不斷成熟的過程中,很難保證所有的開發(fā)人員都能夠有能力守護(hù)架構(gòu),因此除了通過技術(shù)手段守護(hù)架構(gòu),也非常有必要采取一定的手段來提升整個(gè)團(tuán)隊(duì)的認(rèn)知水平和協(xié)作水平。 首先可以在團(tuán)隊(duì)內(nèi)建立架構(gòu)評(píng)審委員會(huì),關(guān)于架構(gòu)的關(guān)鍵決策需要由委員會(huì)來拍板,而不是每個(gè)開發(fā)人員都可以決策。另外在做詳細(xì)的實(shí)現(xiàn)設(shè)計(jì)時(shí),要由有經(jīng)驗(yàn)有能力守護(hù)架構(gòu)的同學(xué)進(jìn)行設(shè)計(jì),并將工作內(nèi)容拆分成更加可操作的Task。通過這種方式將整個(gè)團(tuán)隊(duì)的認(rèn)知水平底線提升到可以守護(hù)架構(gòu)的程度。 上面分享了分層的特點(diǎn)和分層的方法,相信你已經(jīng)對(duì)軟件架構(gòu)分層有了更深入的了解。希望軟件架構(gòu)分層可以融入到我們的開發(fā)設(shè)計(jì)工作中。
七、結(jié)語
本篇文章為大家分享了市面上常見的架構(gòu)分層。架構(gòu)分層的目的是通過關(guān)注點(diǎn)分離來降低系統(tǒng)的復(fù)雜度,同時(shí)滿足單一職責(zé)、高內(nèi)聚、低耦合、提高可復(fù)用性和降低維護(hù)成本。但分層架構(gòu)同樣也有一定的缺點(diǎn),比如開發(fā)成本高、性能略低等問題。實(shí)踐中,架構(gòu)分層并不能解決所有問題,每個(gè)項(xiàng)目可能都有其獨(dú)特的需求和背景,選擇什么樣的架構(gòu)模式,還是要根據(jù)實(shí)情況考慮。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7030瀏覽量
89038 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7494瀏覽量
87961 -
軟件
+關(guān)注
關(guān)注
69文章
4944瀏覽量
87500 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4331瀏覽量
62622
原文標(biāo)題:軟件架構(gòu)分層-你的軟件有沒有分層?
文章出處:【微信號(hào):海馬硬件,微信公眾號(hào):海馬硬件】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論