領(lǐng)域分層
-
【推薦】圖中默認(rèn)上層依賴于下層,箭頭關(guān)系表示可直接依賴,如:開(kāi)放接口層可以依賴于
Web 層,也可以直接依賴于 Service 層,依此類推:
[圖片上傳中...(image.png-2a138f-1632469032140-0)]
-
? 開(kāi)放接口層
:可直接封裝 Service 方法暴露成 RPC 接口览闰;通過(guò) Web 封裝成 http 接口;進(jìn)行網(wǎng)關(guān)安
全控制巷折、流量控制等压鉴。
? 終端顯示層
:各個(gè)端的模板渲染并執(zhí)行顯示的層。當(dāng)前主要是 velocity 渲染锻拘,JS 渲染油吭,JSP 渲染,移
動(dòng)端展示等署拟。
? Web 層
:主要是對(duì)訪問(wèn)控制進(jìn)行轉(zhuǎn)發(fā)婉宰,各類基本參數(shù)校驗(yàn),或者不復(fù)用的業(yè)務(wù)簡(jiǎn)單處理等推穷。
? Service 層
:相對(duì)具體的業(yè)務(wù)邏輯服務(wù)層心包。
? Manager 層
:通用業(yè)務(wù)處理層,它有如下特征:
1) 對(duì)第三方平臺(tái)封裝的層馒铃,預(yù)處理返回結(jié)果及轉(zhuǎn)化異常信息蟹腾。
2) 對(duì) Service 層通用能力的下沉,如緩存方案区宇、中間件通用處理娃殖。
3) 與 DAO 層交互,對(duì)多個(gè) DAO 的組合復(fù)用议谷。
? DAO 層:數(shù)據(jù)訪問(wèn)層炉爆,與底層 MySQL、Oracle、Hbase 等進(jìn)行數(shù)據(jù)交互芬首。
? 外部接口或第三方平臺(tái):包括其它部門 RPC 開(kāi)放接口鲫凶,基礎(chǔ)平臺(tái),其它公司的 HTTP 接口衩辟。
領(lǐng)域模型規(guī)約
? DO(Data Object):此對(duì)象與數(shù)據(jù)庫(kù)表結(jié)構(gòu)一一對(duì)應(yīng),通過(guò) DAO 層向上傳輸數(shù)據(jù)源對(duì)象波附。
? DTO(Data Transfer Object):數(shù)據(jù)傳輸對(duì)象艺晴,Service 或 Manager 向外傳輸?shù)膶?duì)象。
? BO(Business Object):業(yè)務(wù)對(duì)象掸屡,由 Service 層輸出的封裝業(yè)務(wù)邏輯的對(duì)象封寞。
? AO(Application Object):應(yīng)用對(duì)象,在 Web 層與 Service 層之間抽象的復(fù)用對(duì)象模型仅财,極為貼
近展示層狈究,復(fù)用度不高。
? VO(View Object):顯示層對(duì)象盏求,通常是 Web 向模板渲染引擎層傳輸?shù)膶?duì)象抖锥。
? Query:數(shù)據(jù)查詢對(duì)象,各層接收上層的查詢請(qǐng)求碎罚。注意超過(guò) 2 個(gè)參數(shù)的查詢封裝磅废,禁止使用 Map 類
來(lái)傳輸。
詳解
-
查詢視圖
前端或者其它服務(wù)將 Param 對(duì)象作為參數(shù)傳給控制層或者對(duì)外服務(wù)接口荆烈,然后調(diào)用內(nèi)部的服務(wù)類拯勉,服務(wù)類內(nèi)部的中間數(shù)據(jù)和這些數(shù)據(jù)相關(guān)的邏輯可以封裝為 BO ,比如根據(jù) BO 多個(gè)屬性判斷是否符合某個(gè)條件憔购。
如果查詢數(shù)據(jù)則封裝為 Query 對(duì)象作為參數(shù)宫峦,如果需要查詢其它依賴,則可以封裝 Param 對(duì)象作為參數(shù)去查詢玫鸟。DAO 層一般插入和更新的參數(shù)對(duì)象使用 DO 或 Param, 查詢參數(shù)一般使用 Query导绷,刪除參數(shù)一般使用 Param。
-
返回視圖
數(shù)據(jù)訪問(wèn)層通常將數(shù)據(jù)封裝為 DO 對(duì)象傳給 Service 層屎飘,Manager 或 Client 層往往將查詢結(jié)果封裝為 DTO 傳給 Service 層诵次。
通常內(nèi)部服務(wù)層通過(guò) DTO 往外傳輸數(shù)據(jù)。Controller 通常將 DTO 組裝為前端需要的 VO 或者直接將 DTO 外傳 枚碗。
RPC 服務(wù)接口將 DTO 直接返回或者重新封裝為新的 DTO 返回給外部服務(wù)逾一。
另外即使同一個(gè)接口,但是一個(gè)對(duì)內(nèi)使用肮雨,一個(gè)對(duì)外暴露遵堵,盡量使用不同接口,定義不同的參數(shù)和返回值,從而避免因?yàn)樾薷膬?nèi)部或外部的數(shù)據(jù)結(jié)構(gòu)而導(dǎo)致另外一個(gè)受到影響陌宿,這也是單一職責(zé)原則的要求锡足。
單一職責(zé)原則:一個(gè)類應(yīng)該有且只有一個(gè)改變的理由。
也有部分團(tuán)隊(duì) RPC 的請(qǐng)求和響應(yīng)參數(shù)都通過(guò) DTO 來(lái)承載壳坪,通過(guò) XXRequestDTO 和 XXResponseDTO 來(lái)表示舶得。
實(shí)踐分層領(lǐng)域模型能夠提高項(xiàng)目的健壯性、可拓展性和可維護(hù)性爽蝴,降低了系統(tǒng)內(nèi)部各層的耦合度沐批。
參考資料:
- 阿里Java 開(kāi)發(fā)首次華山版
- https://segmentfault.com/a/1190000021701718