領域驅動設計(DDD)分層架構的三種模式


模式一:四層架構

1.User Interface為用戶界面層(或表示層),負責向用戶顯示信息和解釋用戶命令。這里指的用戶可以是另一個計算機系統,不一定是使用用戶界面的人。
2.Application為應用層,定義軟件要完成的任務,並且指揮表達領域概念的對象來解決問題。這一層所負責的工作對業務來說意義重大,也是與其它系統的應用層進行交互的必要渠道。應用層要盡量簡單,不包含業務規則或者知識,而只為下一層中的領域對象協調任務,分配工作,使它們互相協作。它沒有反映業務情況的狀態,但是卻可以具有另外一種狀態,為用戶或程序顯示某個任務的進度。
3.Domain為領域層(或模型層),負責表達業務概念,業務狀態信息以及業務規則。盡管保存業務狀態的技術細節是由基礎設施層實現的,但是反映業務情況的狀態是由本層控制並且使用的。領域層是業務軟件的核心,領域模型位於這一層。
4.Infrastructure層為基礎實施層,向其他層提供通用的技術能力:為應用層傳遞消息,為領域層提供持久化機制,為用戶界面層繪制屏幕組件,等等。基礎設施層還能夠通過架構框架來支持四個層次間的交互模式。

模式二:五層架構

一、三層架構(Data、Context和Interactive)
Data層描述系統有哪些領域概念及其之間的關系,該層專注於領域對象的確立和這些對象的生命周期管理及關系,讓程序員站在對象的角度思考系統,從而讓“系統是什么”更容易被理解。
Context層:是盡可能薄的一層。Context往往被實現得無狀態,只是找到合適的role,讓role交互起來完成業務邏輯即可。但是簡單並不代表不重要,顯示化context層正是為人去理解軟件業務流程提供切入點和主線。
Interactive層主要體現在對role的建模,role是每個context中復雜的業務邏輯的真正執行者,體現“系統做什么”。role所做的是對行為進行建模,它聯接了context和領域對象。由於系統的行為是復雜且多變的,role使得系統將穩定的領域模型層和多變的系統行為層進行了分離,由role專注於對系統行為進行建模。該層往往關注於系統的可擴展性,更加貼近於軟件工程實踐,在面向對象中更多的是以類的視角進行思考設計。
二、五層架構
1.User Interface是用戶接口層,主要用於處理用戶發送的Restful請求和解析用戶輸入的配置文件等,並將信息傳遞給Application層的接口。
2.Application層是應用層,負責多進程管理及調度、多線程管理及調度、多協程調度和維護業務實例的狀態模型。當調度層收到用戶接口層的請求后,委托Context層與本次業務相關的上下文進行處理。
3.Context是環境層,以上下文為單位,將Domain層的領域對象cast成合適的role,讓role交互起來完成業務邏輯。
4.Domain層是領域層,定義領域模型,不僅包括領域對象及其之間關系的建模,還包括對象的角色role的顯式建模。
5.Infrastructure層是基礎實施層,為其他層提供通用的技術能力:業務平台,編程框架,持久化機制,消息機制,第三方庫的封裝,通用算法,等等。
三、六層架構
1.User Interface是用戶接口層,主要用於處理用戶發送的Restful請求和解析用戶輸入的配置文件等,並將信息傳遞給Scheduler層的接口。
2.Scheduler是調度層,負責多進程管理及調度、多線程管理及調度、多協程調度和維護業務實例的狀態模型。當調度層收到用戶接口層的請求后,委托Transaction層與本次操作相關的事務進行處理。
3.Transaction是事務層,對應一個業務流程,比如UE Attach,將多個同步消息或異步消息的處理序列組合成一個事務,而且在大多場景下,都有選擇結構。萬一事務執行失敗,則立即進行回滾。當事務層收到調度層的請求后,委托Context層的Action進行處理,常常還伴隨使用Context層的Specification(謂詞)進行Action的選擇。
4.Context是環境層,以Action為單位,處理一條同步消息或異步消息,將Domain層的領域對象cast成合適的role,讓role交互起來完成業務邏輯。環境層通常也包括Specification的實現,即通過Domain層的知識去完成一個條件判斷。
5.Domain層是領域層,定義領域模型,不僅包括領域對象及其之間關系的建模,還包括對象的角色role的顯式建模。
6.Infrastructure層是基礎實施層,為其他層提供通用的技術能力:業務平台,編程框架,持久化機制,消息機制,第三方庫的封裝,通用算法,等等。

模式三:六邊形架構

有一種方法可以改進分層架構,即依賴倒置原則(Dependency Inversion Principle, DIP),它通過改變不同層之間的依賴關系達到改進目的。
根據該定義,DDD分層架構中的低層組件應該依賴於高層組件提供的接口,即無論高層還是低層都依賴於抽象,整個分層架構好像被推平了。如果我們把分層架構推平,再向其中加入一些對稱性,就會出現一種具有對稱性特征的架構風格,即六邊形架構。六邊形架構是Alistair Cockburn在2005年提出的,在這種架構中,不同的客戶通過“平等”的方式與系統交互。需要新的客戶嗎?不是問題。只需要添加一個新的適配器將客戶輸入轉化成能被系統API所理解的參數就行。同時,對於每種特定的輸出,都有一個新建的適配器負責完成相應的轉化功能。

六邊形架構也稱為端口與適配器,如下圖所示:
在這里插入圖片描述

六邊形每條不同的邊代表了不同類型的端口,端口要么處理輸入,要么處理輸出。對於每種外界類型,都有一個適配器與之對應,外界通過應用層API與內部進行交互。上圖中有3個客戶請求均抵達相同的輸入端口(適配器A、B和C),另一個客戶請求使用了適配器D。假設前3個請求使用了HTTP協議(瀏覽器、REST和SOAP等),而后一個請求使用了AMQP協議(比如RabbitMQ)。端口並沒有明確的定義,它是一個非常靈活的概念。無論采用哪種方式對端口進行划分,當客戶請求到達時,都應該有相應的適配器對輸入進行轉化,然后端口將調用應用程序的某個操作或者向應用程序發送一個事件,控制權由此交給內部區域。
應用程序通過公共API接收客戶請求,使用領域模型來處理請求。我們可以將DDD戰術設計的建模元素Repository(存儲庫)的實現看作是持久化適配器,該適配器用於訪問先前存儲的聚合實例或者保存新的聚合實例。正如圖中的適配器E、F和G所展示的,我們可以通過不同的方式實現資源庫,比如關系型數據庫、基於文檔的存儲、分布式緩存或內存存儲等。如果應用程序向外界發送領域事件消息,我們將使用適配器H進行處理。該適配器處理消息輸出,而上面提到的處理AMQP消息的適配器則是處理消息輸入的,因此應該使用不同的端口。
我們在實際的項目開發中,不同層的組件可以同時開發。當一個組件的功能明確后,就可以立即啟動開發。由於該組件的用戶有多個,並且這些用戶的側重點不同,所以需要提供多個不同的接口。同時,這些用戶的認識也是不斷深入的,可能會多次重構相關的接口。於是,組件的多個用戶經常會找組件的開發者討論這些問題,無形中降低了組件的開發效率。
我們換一種方式,組件的開發者在明確了組件的功能后就專注於功能的開發,確保功能穩定和高效。組件的用戶自己定義組件的接口(端口),然后基於接口寫測試,並不斷演進接口。在跨層集成測試時,由組件開發者或用戶再開發一個適配器就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM