你的項目代碼都是如何分層的?

來源 | https://juejin.cn/post/6844903636334542856

你的項目應該如何正確分層?

1. 背景

的確在這些人眼中分層只是一個形式,前輩們的代碼這麼寫的,其他項目代碼這麼寫的,那麼我也這麼跟着寫。但是在真正的團隊開發中每個人的習慣都不同,寫出來的代碼必然帶着自己的標籤,有的人習慣 controller 寫大量的業務邏輯,有的人習慣在 service 中之間調用遠程服務,這樣就導致了每個人的開發代碼風格完全不同,後續其他人修改的時候,一看,我靠這個人寫的代碼和我平常的習慣完全不同,修改的時候到底是按着自己以前的習慣改,還是跟着前輩們走,這又是個艱難的選擇,選擇一旦有偏差,你的後輩又維護你的代碼的時候,恐怕就要罵人了。

所以一個好的應用分層需要具備以下幾點:

2. 如何進行分層

2.1 阿里規範

在阿里的編碼規範中約束的分層如下:

3 人 2 週上線,2 人 1 週上線,Solo 明天上線!開發週期果然不能用搬磚模式計算...

開放接口層: 可直接封裝 Service 方法暴露成 RPC 接口; 通過 Web 封裝成 http 接口; 進行 網關安全控制、流量控制等。

終端顯示層: 各個端的模板渲染並執行顯示的層。當前主要是 velocity 渲染,JS 渲染, JSP 渲染,移動端展示等。

Web 層: 主要是對訪問控制進行轉發,各類基本參數校驗,或者不復用的業務簡單處理等。

Service 層: 相對具體的業務邏輯服務層。

Manager 層: 通用業務處理層,它有如下特徵: 1. 對第三方平臺封裝的層,預處理返回結果及轉化異常信息; 2. 對 Service 層通用能力的下沉,如緩存方案、中間件通用處理; 3. 與 DAO 層交互,對多個 DAO 的組合複用。

DAO 層: 數據訪問層,與底層 MySQL、Oracle、Hbase 進行數據交互。

阿里巴巴規約中的分層比較清晰簡單明瞭,但是描述得還是過於簡單了,以及 service 層和 manager 層有很多同學還是有點分不清楚之間的關係,就導致了很多項目中根本沒有 Manager 層的存在。下面介紹一下具體業務中應該如何實現分層

2.2 優化分層

從我們的業務開發中總結了一個較爲的理想模型, 這裏要先說明一下由於我們的 rpc 框架選用的是 thrift 可能會比其他的一些 rpc 框架例如 dubbo 會多出一層, 作用和 controller 層類似

想接私活時薪再翻一倍,建議根據這幾個開源的 SpringBoot 項目(含小程序)

  1. 最上層 controller 和 TService 是我們阿里分層規範裏面的第一層: 輕業務邏輯,參數校驗,異常兜底。通常這種接口可以輕易更換接口類型, 所以業務邏輯必須要輕,甚至不做具體邏輯。

2.Service:業務層,複用性較低,這裏推薦每一個 controller 方法都得對應一個 service, 不要把業務編排放在 controller 中去做,爲什麼呢?如果我們把業務編排放在 controller 層去做的話,如果以後我們要接入 thrift, 我們這裏又需要把業務編排在做一次,這樣會導致我們每接入一個入口層這個代碼都得重新複製一份如下圖所示:

銀行科技到底怎麼樣?我曾經的四年告訴你 !

這樣大量的重複工作必定會導致我們開發效率下降,所以我們需要把業務編排邏輯都得放進 service 中去做:

如何畫好架構圖

3.Mannager:可複用邏輯層。這裏的 Mannager 可以是單個服務的,比如我們的 cache,mq 等等,當然也可以是複合的,當你需要調用多個 Mannager 的時候,這個可以合爲一個 Mannager,比如邏輯上的連表查詢等。如果是 httpMannager 或 rpcMannager 需要在這一層做一些數據轉換

4.DAO:數據庫訪問層。主要負責 “操作數據庫的某張表,映射到某個 java 對象”,dao 應該只允許自己的 Service 訪問,其他 Service 要訪問我的數據必須通過對應的 Service。

3. 分層領域模型的轉換

在阿里巴巴編碼規約中列舉了下面幾個領域模型規約:

每一個層基本都自己對應的領域模型,這樣就導致了有些人過於追求每一層都是用自己的領域模型,這樣就導致了一個對象可能會出現 3 次甚至 4 次轉換在一次請求中,當返回的時候同樣也會出現 3-4 次轉換,這樣有可能一次完整的請求 - 返回會出現很多次對象轉換。如果在開發中真的按照這麼來,恐怕就別寫其他的了,一天就光寫這個重複無用的邏輯算了吧。

所以我們得采取一個折中的方案:

  1. 允許 Service/Manager 可以操作數據領域模型,對於這個層級來說,本來自己做的工作也是做的是業務邏輯處理和數據組裝。

2.Controller/TService 層的領域模型不允許傳入 DAO 層,這樣就不符合職責劃分了。

  1. 同理,不允許 DAO 層的數據傳入到 Controller/TService.

這代碼有毒...

4. 總結

總的來說業務分層對於代碼規範是比較重要,決定着以後的代碼是否可複用,是否職責清晰,邊界清晰。

當然這種分層其實見仁見智, 團隊中的所有人的分層習慣也不同,所以很難權衡出一個標準的準則,總的來說只要滿足職責邏輯清晰,後續維護容易,就是好的分層。

最後,如果你的團隊有更好的分層,或者上面所描述的有什麼錯誤的地方還請留言指正一下。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/VuOrZFDo9DlgumN7LIHnZQ