DDD架構為什麼應該首選六邊形架構?

来源:https://www.cnblogs.com/Jcloud/archive/2023/07/21/17571346.html
-Advertisement-
Play Games

採用依賴倒置原則後的分層架構和六邊形架構,實際上都符合整潔架構設計理念。但是六邊形架構中使用埠與適配器,讓應用程式能夠以一致的方式被用戶、程式、自動化測試、批處理腳本所驅動,同時能夠讓應用程式邊界更加清晰,從而能更好地防止領域層和應用層邏輯泄露到外層。 ...


一、傳統分層架構

分層架構的一個重要原則是:每層只能與位於其下方的層發生耦合。

分層架構分兩種:一種是嚴格分層架構,規定某層只能與直接位於其下方的層發生耦合;另一種是鬆散分層架構,允許任意上方層與任意下方層發生耦合。

下圖是一個典型的DDD傳統分層架構。

以上分層架構中各層都有自己的職責:

用戶介面層負責處理用戶請求和用戶顯示;

應用層實現不同業務場景下的用例或業務流程。其中應用服務通常接收來自用戶介面層的請求,然後通過資源庫獲取聚合實例,最後執行相應的命令操作,如下示例:

// 應用層的用例 
public void cancelOrder(Long orderId) { 
    Order order = orderRepository.findById(orderId); 
    // 領域層的業務邏輯 
    order.cancel() 
    orderRepository.save(order); 
}

領域層實現系統的核心業務邏輯,主要包含基於DDD業務建模產生的領域模型,這裡的業務邏輯不同於應用層中的業務流程,如上代碼示例;

基礎設施層為其它各層提供通用的技術和基礎服務,比如數據持久化功能。

二、傳統分層架構的問題

DDD中資源庫(Repository)用來獲取或持久化聚合,每個聚合都擁有一個對應的資源庫。由此可見資源庫應該和聚合位於同一層,資源庫介面定義應該位於領域層,而資源庫介面實現需要依賴基礎設施層的持久化機制,此時資源庫介面實現放在哪一層對傳統分層架構來說是個問題。

如果把資源庫介面實現放在基礎設施層,那麼基礎設施層就會向上依賴領域層,這樣就違反了分層架構的原則:每層只能與位於其下方的層發生耦合。

或者可以放在領域層,但是這樣會使領域層依賴數據持久化的實現細節,導致領域層不再是一個穩定層。

也可以放在應用層,不過和放在領域層會有同樣的問題。

那有沒有更好的方式呢?

有,採用依賴倒置,打破分層架構原則。

三、依賴倒置原則

依賴倒置(或依賴反轉)原則(Dependency inversion principle,DIP),由Bob大叔提出,其定義如下:

高層模塊不應該依賴於低層模塊,兩者都應該依賴於抽象。 抽象不應該依賴於細節,細節應該依賴於抽象。

我們把資源庫介面實現放在基礎設施層,讓基礎設施層向上依賴領域層。雖然這樣違背了分層架構原則,但是卻符合依賴倒置原則:領域層(高層模塊)不依賴基礎設施層(低層模塊),兩者都依賴於資源庫介面(抽象)。採用了依賴倒置後,同時調整下基礎設施層位置,此時分層架構如下圖:

四、六邊形架構

分層架構採用依賴倒置原則後,實際上已經不存在分層的概念了。無論是高層還是低層,都只依賴於抽象,好像把整個分層架構給推平了一樣。推平後的分層架構如下圖:

給推平的分層架構補上左側對稱的另一半,其結果就類似六邊形架構,如下圖是六邊形架構。

六邊形架構也叫埠和適配器。在這種架構中,針對系統輸入輸出的不同交互方式,比如http、rpc、mq、數據持久化等,都有與之對應的適配器,適配器又通過應用層API與內部進行交互。

六邊形架構讓應用程式能夠以一致的方式被用戶、程式、自動化測試、批處理腳本所驅動,而且能夠讓應用程式的邊界更加清晰。有關六邊形架構的詳細信息可以查看 六邊形架構原文翻譯

五、為什麼不選擇整潔架構?

整潔架構是Bob大叔在其《架構整潔之道》一書中,對六邊形架構和其他類似架構做了總結和抽象之後,提出的一種架構設計理念。

書中總結出,六邊形架構和其他類似架構設計出來的系統,都具有相同的特點:

獨立於框架:這些系統的架構並不依賴某個功能豐富的框架之中的某個函數。框架可以被當成工具來使用,但不需要讓系統來適應框架。 可被測試:這些系統的業務邏輯可以脫離UI、資料庫、Web服務以及其他的外部元素來進行測試。 獨立於UI:這些系統的UI變更起來很容易,不需要修改其他的系統部分。 獨立於資料庫:我們可以輕易將這些系統使用的Oracle、SQL Server替換成Mongo、BigTable、CouchDB之類的資料庫。因 為業務邏輯與資料庫之間已經完成瞭解耦。 獨立於任何外部機構:這些系統的業務邏輯並不需要知道任何其他外部介面的存在。

綜合以上所有架構的設計理念,Bob大叔提出了整潔架構設計理念,如下圖。

以上圖中同心圓分別代表了軟體系統的不同層次,通常越靠近中心,其所在的軟體層次就越高。

整潔架構規定了層之間的依賴關係規則:內層(高層)不依賴外層(低層),六邊形架構層之間的依賴關係也遵從此規則。

至此可以認為整潔架構是一種架構設計的指導思想,六邊形架構是整潔架構的一種具體的架構設計。

六、總結

採用依賴倒置原則後的分層架構和六邊形架構,實際上都符合整潔架構設計理念。但是六邊形架構中使用埠與適配器,讓應用程式能夠以一致的方式被用戶、程式、自動化測試、批處理腳本所驅動,同時能夠讓應用程式邊界更加清晰,從而能更好地防止領域層和應用層邏輯泄露到外層。

七、參考

1.《實現領域驅動設計》

2.《架構整潔之道》

作者:京東零售 加文雄

來源:京東雲開發者社區


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 簡述 本文主要介紹使用 [CloudCanal](https://www.clougence.com?kw=cnblogs_20230721) 做數據遷移同步時如何對特定數據做脫敏處理。 ## 技術點 ### 自定義代碼 CloudCanal 允許用戶上傳業務代碼到數據任務中,完成數據遷移、同 ...
  • 一、哪些因素會成為系統的瓶頸 CPU:如果存在大量的計算,他們會長時間不間斷的占用CPU資源,導致其他資源無法爭奪到CPU而響應緩慢,從而帶來系統性能問題,例如頻繁的FullGC,以及多線程造成的上下文頻繁的切換,都會導致CPU繁忙,一般情況下CPU使用率<75%比較合適。 記憶體:Java記憶體一般是 ...
  • 我們智能客服知識庫機器人已經開發完成,後端資料庫是使用的qdrant向量資料庫,但是該資料庫並沒有導出備份功能,所以我按簡單的純前端實現知識庫導出excel數據 使用第三方庫(如SheetJS) SheetJS是一個流行的JavaScript庫,可幫助處理Excel文件。您可以使用SheetJS來將 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 背景 愉快的雙休周末剛過完,早上來忽然被運營通知線上業務掛了,用戶無法下單。卧槽,趕緊進入debug模式,一查原來是服務端返回的數據有問題,趕緊問了服務端,大佬回覆說是業務部門配置套餐錯誤。好在主責不在我們,不過趕緊寫了復盤文檔,主動找自 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • 1.添加函數修改img的屬性; /** * * @param {*} idName 傳入的id,獲取改img的dom,添加相應的數學 */ export const proxyImg = (idName) => { const img = document.getElementById(idName ...
  • 打開前端項目中的 package.json,會發現眾多工具已經占據了我們開發日常的各個角落,它們的存在於我們的開發而言是不可或缺的。有沒有想過這些工具的功能是如何實現的呢?沒錯,抽象語法樹 (Abstract Syntax Tree) 就是上述工具的基石。 ...
  • TCP/IP是一種分層模型,它將通信協議分解為五個層次,每個層次都有特定的功能和任務。以下是TCP/IP五層的處理流程: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...