All problems in computer science can be solved by another level of indirection -- David Wheeler
計(jì)算機(jī)科學(xué)中的任何問(wèn)題,都可以通過(guò)加上一層邏輯層來(lái)解決。-- David Wheeler
總之,分層就是有好處
在計(jì)算機(jī)領(lǐng)域,“分層” 概念無(wú)處不在。比如 web 開(kāi)發(fā)時(shí)的 MVC ,網(wǎng)絡(luò)編程時(shí)的 OSI 參考模型和 TCP/IP 協(xié)議族。
但是為什么要進(jìn)行分層呢?不同的書(shū)有不同的說(shuō)法。
在《圖解TCP/IP》這本書(shū)這樣說(shuō):
在這一模型中,每個(gè)分層都接收它下一層所提供的特定服務(wù),并且負(fù)責(zé)為自己的上一層提供特定的服務(wù)。上下層之間進(jìn)行交互時(shí)所遵循的約定叫做“接口”。
在我看來(lái),說(shuō)了等于白說(shuō)。:-P
而《企業(yè)應(yīng)用架構(gòu)模式》開(kāi)篇第 1 章是這樣說(shuō)的:
在分解復(fù)雜的軟件系統(tǒng)時(shí),軟件設(shè)計(jì)者用得最多的技術(shù)之一就是分層。
當(dāng)用分層的觀點(diǎn)來(lái)考慮系統(tǒng)時(shí),可以將各個(gè)子系統(tǒng)想像成按照“多層蛋糕”的形式來(lái)組織,每一層都依托在其下層之上。在這種組織方式下,上層使用了下層定義的各種服務(wù),而下層對(duì)上層一無(wú)所知。另外,每一層對(duì)自己的上層隱藏其下層的細(xì)節(jié)。
Marting Fowler在第 1 章后面,又舉了一個(gè)表現(xiàn)層,領(lǐng)域?qū)?,?shù)據(jù)源層的例子。但是個(gè)人認(rèn)為依然沒(méi)有把為什么要分層說(shuō)透。
對(duì)于為什么要分層,我見(jiàn)過(guò)的大多數(shù)文章說(shuō)的只是它帶來(lái)的好處。比如下層修改實(shí)現(xiàn),不影響上層使用;分離關(guān)注點(diǎn)等。但是為什么會(huì)帶來(lái)這些好處?看似很傻的一個(gè)問(wèn)題,其實(shí)很難回答。
兩個(gè)例子幫助你認(rèn)識(shí)“分層”
我們先通過(guò)兩個(gè)例子給大家一些感性的認(rèn)識(shí)。
自動(dòng)駕駛
用分層的思維來(lái)看開(kāi)車這件事情是這樣的:
| 分層 | 具體內(nèi)容 |
|---|---|
| 人的意圖 | 前行,不上坡,右轉(zhuǎn)彎 |
| 人的操作 | 踩著油門(mén),瞥一眼后視鏡,方向盤(pán)打右 |
| 汽車運(yùn)行 | 根據(jù)踩下油門(mén)的程度,發(fā)動(dòng)機(jī)輸出動(dòng)力,而方向盤(pán)打右轉(zhuǎn)動(dòng)轉(zhuǎn)向拉桿 |
| 發(fā)動(dòng)機(jī) | 進(jìn)氣,壓縮,點(diǎn)燃,排氣 |
| 更底層省略.... | 更底層省略 ..... |
因?yàn)橛辛朔謱?,?dāng)我們要實(shí)現(xiàn)自動(dòng)駕駛汽車時(shí),要解決的就只是“人的操作”這一層的問(wèn)題,而不需要實(shí)現(xiàn)“人的操作”以下所有的層,也就是不需要自己從頭造汽車(不是絕對(duì),但是絕對(duì)不需要從頭造所有的部分)。
IoT 云云對(duì)接
總要舉一個(gè)軟件開(kāi)發(fā)領(lǐng)域的例子吧。我們舉一個(gè) IoT 云云對(duì)接的例子。
當(dāng)?shù)谌皆葡肟刂?M云的空調(diào)時(shí),系統(tǒng)的外觀是這樣的:

如果我說(shuō)用分層的方式,想必有人馬上想要說(shuō) MVC blabla……。事實(shí)上,我不贊同這樣。因?yàn)樵谖已劾?,MVC 解決只是技術(shù)層面的問(wèn)題。從技術(shù)角度分層的優(yōu)先級(jí)比從業(yè)務(wù)角度分層的優(yōu)先級(jí)低。換句話說(shuō),分層可以從多個(gè)角度進(jìn)行,不同的角度有不同的優(yōu)先級(jí)。
從業(yè)務(wù)角度如何分層呢?

我們可以將設(shè)備控制器分成:指令生成器和指令下發(fā)器。
我們也來(lái)說(shuō)說(shuō)這樣設(shè)計(jì)帶來(lái)的好處 :-P :
- 協(xié)議轉(zhuǎn)換器的修改,不會(huì)影響設(shè)備控制器的邏輯。反之亦然。
- 第三方云不需要知道如何組織空調(diào)的二進(jìn)制,只需要表達(dá)自己的意圖:空調(diào)20度。使用人類可讀的json結(jié)構(gòu)。
- 不同云之間的對(duì)接互不影響。
為什么分層能帶來(lái)這些好處?
為什么分層能帶來(lái)這些好處?剛畢業(yè)那會(huì),我經(jīng)常這樣問(wèn)自己。后來(lái),經(jīng)過(guò)一位高人的指導(dǎo),再加上看過(guò)《面向?qū)ο蠓治雠c設(shè)計(jì)》之后,終于明白了:
開(kāi)發(fā)軟件本身是一件很復(fù)雜的事情(必須認(rèn)識(shí)到這一點(diǎn))。而我們?nèi)祟惔竽X的能力是有限的,不可能同時(shí)處理太多的復(fù)雜性。我們可以通過(guò)將復(fù)雜性分解、抽象、分層,一次只需要處理一個(gè)部分復(fù)雜性,而不是所有。
所以,“分層”并不能讓復(fù)雜性消失,而是讓我們的大腦在能力范圍內(nèi)處理相對(duì)重要的層面的復(fù)雜性,而忽略那些不那么重要的細(xì)節(jié)。
比如開(kāi)發(fā)一個(gè)HR系統(tǒng),你的大腦應(yīng)集中精力放在業(yè)務(wù)邏輯上,而不是操作系統(tǒng)如何與硬件打交道(并不是說(shuō)操作系統(tǒng)原理不重要,只是在HR系統(tǒng)上不重要)。

小結(jié)
軟件開(kāi)發(fā)所面對(duì)的復(fù)雜性超出了我們?nèi)祟惔竽X一次性能處理的范圍,而分層是一種手段,幫助我們?nèi)祟愔恍枰幚硐鄬?duì)重要的層面的復(fù)雜性,而忽略相對(duì)不重要層面的復(fù)雜性。進(jìn)而使我們以更低的成本達(dá)到目的。而好處只是副產(chǎn)品。
接下來(lái)的問(wèn)題,如何進(jìn)行分層呢?分層好壞的標(biāo)準(zhǔn)是什么?留給大家思考。
最后,強(qiáng)烈推介《面向?qū)ο蠓治雠c設(shè)計(jì)》這本書(shū)。不要以為這又是一本只講 UML 的書(shū)。