應用架構 DDD
應用架構區別
好的應用架構,都遵循一些共同模式,不管是六邊形架構、洋蔥圈架構、整潔架構、還是 COLA 架構,都提倡以業務爲核心,解耦外部依賴,分離業務複雜度和技術複雜度。
分層架構(Layered Architecture)
分層架構就是將業務應用劃分爲對應的層級模塊。每個層職責不同。
四層結構定義:
-
接口層: 統一處理系統對外的服務接口,可以是直接查詢,也可以是三方系統對接。
-
應用層: 調用各個領域完成一個具體的業務流程應用,不需要關心具體的業務實現。
-
領域層: 實際完成業務邏輯處理的地方,包含領域模型和領域服務,無須關心顯示及存儲等相關問題。
-
基礎設施層: 提供底層支撐功能,包括持久化、序列化與反序列化、消息中間件等。
優點:
-
可降低層級之間依賴;
-
利於層級模塊複用;
-
安全性高,外部系統只從接口層訪問,統一入口點;
-
項目結構清晰,簡單。
常見兩種分層架構圖:
圖一:四層
圖二:五層
六邊形架構(Hexagonal Architecture)
六邊形架構可以理解爲 “去結構化” 的架構,系統內部與外界的交互過程通過適配器來完成,沒有層次,所有交互雙方只知道適配器的存在,不用知曉對方的存在。
六邊形又稱爲端口適配器模式。六邊形架構將系統分爲內部和外部,內部代表具體的業務邏輯,也就是 DDD 中強調的領域模型(其中包含領域服務,對業務概念建立的模型等);外部代表基礎設施和應用等,類似 RESTful API, SOAP, AMQP, 或者數據庫,內存,文件系統,以及自動化測試。 內部和外部之間通過端口通信。端口代表協議,通常是以 API 呈現。端口的具體實現是適配器,負責對接具體的外部系統或內部邏輯。該架構可以非常容易的實現外部替換、依賴倒置、自動測試等功能。
一個端口對應多個適配器,是對一類外部系統的歸納。
適配器分爲主適配器和次適配器:
-
主適配器(Driving Adapter):代表接收用戶輸入,調用端口並返回數據。
-
次適配器(Driven Adapter):實現應用的出口端口,向外部工具執行操作。
六邊形架構優點:
-
業務領域的邊界更加清晰。
-
更好的可擴展性。(比如需要新增一種協議(數據庫、MQ...)的支持,那麼只需要定義一組端口 - 適配器即可。對原有端口 - 適配器不影響)
-
對測試的友好支持。
-
更容易實施 DDD。
整潔架構(Clean Architecture)
整潔架構(又名洋蔥架構 Onion Architecture),六邊形架構的變種。
整潔架構是 Robot C.Martin 在《整潔架構之道》一書中提出來的架構設計思想。它以圓環的形式把系統分成了幾個不同的層次,因此又被稱爲洋蔥架構。
在整潔架構裏,同心圓代表應用軟件的不同部分,從裏到外依次是領域模型、領域服務、應用服務、最外圍是容易變化的內容,如界面和基礎設施(如數據存儲等)。整潔架構是以領域爲中心,不是以數據爲中心。
整潔架構最主要原則是依賴原則,它定義了各層的依賴關係,越往裏,依賴越低,代碼級別越高。外圓代碼依賴只能指向內圓,內圓不知道外圓的任何事情。一般來說,外圓的聲明(包括方法、類、變量)不能被內圓引用。同樣的,外圓使用的數據格式也不能被內圓使用。
-
Domain Model:業務模型,對應 DDD 中的 Entity、值對象等。
-
Domain Services:核心業務邏輯。
-
Application Services:應用的輸入輸出層。
-
User Interface/Tests/Infrastructure:適配器層(例如數據庫、用戶界面及外部服務)。
優點:
-
各層職責清晰,提高了大型複雜項目的可維護性。
-
結合 DDD,使項目以領域模型爲主。
-
保證內部核心領域的獨立和無依賴,外部技術細節可以通過接口和適配器隨時更換,在不丟失任何業務邏輯的情況下替換掉整個技術實現,從而增加系統的靈活性和可測性。
DDD 架構(Domain Driven Design Architecture)
準確地說,DDD 不是架構,而是一種開發思想。 DDD 帶來的最大改變是讓我們得以從 “數據驅動” 轉向 “領域驅動”,讓我們知道領域是應用的核心,其它都是技術細節,隨時可以被替換。
DDD 四層架構見分層架構圖一。
DDD 採用統一語言,避免組件劃分過程中的邊界錯位。讓業務架構和系統架構形成綁定關係,從而建立針對業務變化的高響應力架構。
-
戰略層面:針對業務問題分析和分解,通過識別核心問題域來降低分析的複雜度。
-
戰術層面:識別問題域裏的不同業務上下文來進行面向業務需求的組件化。
DDD 基本概念:
-
通用語言:通過畫領域模型圖、類圖來建立一種溝通關係。
-
實體 Entity:從屬於某個聚合根。實體具有 id,有生命週期。
-
值對象 Value Object:無生命週期,歸屬具體的實體。
-
聚合 Aggregate:領域模型最底層的邊界。邏輯邊界。一個聚合只有一個聚合根。
-
聚合根 Aggregate Root:最抽象、最普遍的特徵。也叫做根實體。
-
工廠 Factory:隱藏對象的複雜創建邏輯。
-
倉庫 Repository:封裝獲取對象的邏輯。
-
限界上下文 Bounded Context:定義了每個模型的應用範圍,可理解爲一個子域對應一個上下文。一個上下文可能包含多個聚合,每個聚合都有一個根實體,叫做聚合根。
COLA 架構 (Clean Object-oriented & Layered Architecture)
一方面 COLA 是一種架構思想,是整合了洋蔥圈架構、適配器架構、DDD、整潔架構、TMF 等架構思想的一種應用架構。
基於擴展點 + 元數據 + CQRS+DDD 的應用架構:擴展性好,貫徹了 OO 思想,有一套完整的規範標準,並採用 CQRS 和領域建模技術,很大程度可降低應用的複雜度。
層級職責:
-
cola-adapter:負責對前端展示的路由和適配。
-
cola-app:負責獲取輸入,組裝 context,做輸入校驗,調用領域層做業務處理。
-
cola-client:二方庫組件,提供應用對外的接口。
-
cola-domain:領域層,封裝核心業務邏輯。
-
cola-infrastructure:基礎設施層,處理技術細節加領域防腐。
-
start:spring boot 啓動層。
圖來源:https://blog.csdn.net/significantfrank/article/details/110934799
CQRS 架構
**命令查詢職責分離(CQRS)是指讀取和寫入分別擁有單獨的數據結構。**使用 CQRS 理由是,在複雜領域中,使用單一模型處理讀取和寫入過於複雜,我們可以通過分離模型來簡化設計和實現。
其基本思想在於任何一個對象的方法可以分爲以下兩類:
-
命令(Command):不返回任何結果(void),但會改變對象的狀態。
-
查詢(Query):返回結果,但是不會改變對象的狀態,對系統沒有副作用。
CQRS 查詢和更新數據(命令)模型不一樣,CQRS 強調的是 command 和 query 訪問的數據模型不同,分別根據 command 與 query 需求的不同特性設計數據模型。命令模型數據變更後,需同步給查詢模型。
在很多系統業務設計上,數據庫裏數據模型很難和業務領域模型一致,所以 DDD 中有領域模型(Domain model)的概念,在領域層轉換成對應的數據庫 DO(Data Object)實體。
優點:
-
讀寫邏輯高度解耦,符合單一職責(模型分離,可獨立設計)
-
獨立部署有更好的伸縮性
缺點:
-
帶來了複雜性,傳統過程式編程直接用一個模型搞定,現在變成兩個模型,還要結合一些 DDD 的思想才能更好的實現;
-
數據非強一致性,是最終一致性。(個人理解:如果同步實現保證強一致性的話,命令端寫成功之後還需要往查詢端寫,會降低系統可用性)
參考資料
-
<中臺落地手記: 業務服務化與數據資產化>
-
代碼精進之路: 從碼農到工匠
-
領域驅動設計(Thoughtworks 洞見)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/I6h14qPNQK9-m4KrgGnKqg