一、背景
一個(gè)好的應(yīng)用分層需要具備以下幾點(diǎn):
方便后續(xù)代碼進(jìn)行維護(hù)擴(kuò)展;
分層的效果需要讓整個(gè)團(tuán)隊(duì)都接受;
各個(gè)層職責(zé)邊界清晰。
二、如何進(jìn)行分層
2.1、阿里規(guī)范
在阿里的編碼規(guī)范中約束的分層如下:
在這里插入圖片描述
開(kāi)放接口層:可直接封裝 Service 方法暴露成RPC接口;通過(guò) Web 封裝成 http 接口;進(jìn)行 網(wǎng)關(guān)安全控制、流量控制等。
終端顯示層:各個(gè)端的模板渲染并執(zhí)行顯示的層。
Web 層:主要是對(duì)訪問(wèn)控制進(jìn)行轉(zhuǎn)發(fā),各類(lèi)基本參數(shù)校驗(yàn),或者不復(fù)用的業(yè)務(wù)簡(jiǎn)單處理等。
Service 層:相對(duì)具體的業(yè)務(wù)邏輯服務(wù)層。
Manager 層:通用業(yè)務(wù)處理層,它有如下特征:
對(duì)第三方平臺(tái)封裝的層,預(yù)處理返回結(jié)果及轉(zhuǎn)化異常信息;
對(duì)Service層通用能力的下沉,如緩存方案、中間件通用處理;
與DAO層交互,對(duì)多個(gè)DAO的組合復(fù)用。
DAO 層:數(shù)據(jù)訪問(wèn)層,與底層 MySQL、Oracle、PostgreSQL進(jìn)行數(shù)據(jù)交互。
阿里巴巴規(guī)約中的分層比較清晰簡(jiǎn)單明了,但是描述得還是過(guò)于簡(jiǎn)單了,以及Service層和Manager層有很多同學(xué)還是有點(diǎn)分不清楚之間的關(guān)系,就導(dǎo)致了很多項(xiàng)目中根本沒(méi)有Manager層的存在。下面介紹一下具體業(yè)務(wù)中應(yīng)該如何實(shí)現(xiàn)分層。
2.2、優(yōu)化分層
從我們的業(yè)務(wù)開(kāi)發(fā)中總結(jié)了一個(gè)較為的理想模型:
在這里插入圖片描述
最上層Controller和TService是我們阿里分層規(guī)范里面的第一層:輕業(yè)務(wù)邏輯,參數(shù)校驗(yàn),異常兜底。通常這種接口可以輕易更換接口類(lèi)型,所以業(yè)務(wù)邏輯必須要輕,甚至不做具體邏輯。
Service:業(yè)務(wù)層,復(fù)用性較低,這里推薦每一個(gè)Controller方法都得對(duì)應(yīng)一個(gè)Service,不要把業(yè)務(wù)編排放在Controller中去做,為什么呢?如果我們把業(yè)務(wù)編排放在Controller層去做的話,如果以后我們要接入其他框架,我們這里又需要把業(yè)務(wù)編排在做一次,這樣會(huì)導(dǎo)致我們每接入一個(gè)入口層這個(gè)代碼都得重新復(fù)制一份如下圖所示:
在這里插入圖片描述
這樣大量的重復(fù)工作必定會(huì)導(dǎo)致我們開(kāi)發(fā)效率下降,所以我們需要把業(yè)務(wù)編排邏輯都得放進(jìn)Service中去做:
在這里插入圖片描述
Mannager:可復(fù)用邏輯層。這里的Mannager可以是單個(gè)服務(wù)的,比如我們的Cache,MQ等等,當(dāng)然也可以是復(fù)合的,當(dāng)你需要調(diào)用多個(gè)Mannager的時(shí)候,這個(gè)可以合為一個(gè)Mannager,比如邏輯上的連表查詢等。如果是httpMannager或rpcMannager需要在這一層做一些數(shù)據(jù)轉(zhuǎn)換。
DAO:數(shù)據(jù)庫(kù)訪問(wèn)層。主要負(fù)責(zé)“操作數(shù)據(jù)庫(kù)的某張表,映射到某個(gè)java對(duì)象”,Dao應(yīng)該只允許自己的Service訪問(wèn),其他Service要訪問(wèn)我的數(shù)據(jù)必須通過(guò)對(duì)應(yīng)的Service。