一、概述
對于比較複雜的業務流程,傳統的分層架構等在後續代碼可擴充性,可維護性,可測試上存在很大的問題,最近也在學習和研究領域模型相關的設計,實踐總結一下。
代碼倉庫:Jmqtt,隻關注其中的jmqtt-admin子產品即可,歡迎老鐵給個star
二、傳統的分層架構
如圖:

這是一個極簡的三層架構模式,每層的關系和職責大約是:
- WEB層(Controller層):提供http接口給外部,處理參數的接收和響應;依賴業務層;與之類似的層包括:Gateway層,OpenAPI層,服務層(提供RPC給其他服務)等
- 業務層(Service層):負責處理業務邏輯,包括參數校驗,資料處理轉換,業務邏輯處理,與資料層互動等;依賴資料層
- 資料層(DAO層):負責處理資料持久化,資料緩存等;與之類似的層包括:整合層(基礎依賴層,處理MQ,定時任務等基礎依賴),外部依賴層(依賴其他服務提供的RPC服務接口,http接口等服務)
- 通用層:工具類等處理
三、領域驅動設計的六邊形架構
六邊形架構網上已經有很多解釋和說明了,這裡我說下我的了解:
- 領域層(domain層):處理領域模型的地方,在領域設計中的實體,值對象,領域服務,聚合根,聚合等都放在這裡。不依賴任何外部子產品,提供接口(adapter)給外部實作進行互動。
- 應用層(application層):依賴領域層,可對标三層架構中的業務層進行了解,不過領域設計中的應用層隻負責業務流程編排,不負責資料完整性校驗,業務邏輯處理等。依賴領域層,調用領域層的領域服務或聚合根進行業務編碼
- 資料層(dal層):處理資料持久化的邏輯,實作領域層的adapter接口,依賴領域層。
- 整合層(intergration層):處理外部依賴,包括其他服務提供的RPC服務,外部Http接口服務等,實作領域層adapter接口,依賴領域層。這裡還有一層防腐層(ACL),主要是處理對第三方依賴的強依賴,防止因第三方服務不可用或服務接口資料改動,導緻領域服務不可用。
- 基礎依賴層(intergration層):處理MQ,定時任務等基礎依賴,可與整合層放在一起,主要處理第三方中間件依賴等,實作領域層的adapter接口,依賴領域層。
- 接口服務層(facade/client層):主要暴露對外提供的接口服務,封裝DTO,CQRS,領域事件對象等,不依賴任何外部服務,領域層依賴該子產品,放在這裡主要是為了說明。
- 測試層(test層):主要負責單元測試和內建測試,依賴所有層,放在這裡主要是為了說明。
其它還沒标明的一些層:
- WEB層(controller層):依賴領域層,提供http接口服務,其它類似Gateway層等
- 通用層(common層):各層的工具在各層自行封裝,降低依賴。也可以引入一個通用Common層,比如日志處理等。
四、實踐案例
背景:jmqtt-admin是一個iot mq的管理平台,背景主要是提供Iot裝置的管理,監控,資料采集等。
下面是jmqtt-admin的子產品設計:
目前代碼整個管理平台還在開發中,整套後端代碼會采用領域設計的方式開發,歡迎持續關注,
附子產品依賴圖:
Gateway依賴WEB層,可複用WEB層的攔截器等進行處理。
五、聊聊差別
分層架構:
- 一般是資料模組化管道,接到業務需求後,技術手段上首先是進行資料模組化,再進行開發。
- 重業務層,一般沒有領域的概念,重業務層意味着基本所有核心業務都是在業務層解決的,對下直接依賴資料層,資料層上一般是提供接口和資料DO對象,導緻切換底層資料源時,上層業務層可能也需要做一些改動(耦合高)。同理,改動業務層也可能涉及底層依賴的改動
- 擴充比較難:每次改動都需要改動業務層,若業務複雜,可能一個方法裡包含了非常多的邏輯,包括:驗參,處理業務邏輯,請求第三方依賴擷取資料,資料轉換,資料持久化等等
- 較難測試:對于一個業務,往往業務大了,想要測試這個業務方法時,需要将業務邏輯依賴的所有服務都啟動起來,單測比較麻煩。
領域驅動設計:
- 表現為領域驅動設計:由技術專家+業務專家共同模組化(梳理業務流程,對焦通用語言,劃分領域邊界),技術上表現先開發領域層,定義領域模型和接口服務,再開發其他具體實作
- 重領域層,核心變動和經常改變的應該都是在領域層,其他層變動不應該影響領域層,領域層的變動應該隻影響上層應用層。領域層的實體除了負責簡單資料屬性外,還要處理業務邏輯
- 較為複雜,需要和前期學習成本:如圖,比較複雜。在前期業務簡單時,開發速度比分層架構慢,但是後續可擴充性和可維護性及可測試行強很多(領域模型區分了變化與不變的邊界。頻繁變化的邏輯應該都在領域層)
- 不一定适用所有業務應用,不過領域劃分的思想适合用來劃分微服務,限制相關開發,一旦形成約定,對于代碼了解成本也會降低一些。