在前文中,我從基礎程式碼的角度探討了如何運用領域驅動設計(DDD)來實現高內聚低耦合的程式碼。本篇文章將從專案架構的角度,繼續探討三層架構與DDD之間的演化過程,以及DDD如何優化架構的問題。
三層架構作為一種常見的軟體架構模式,將應用程式分為展示層、業務邏輯層和資料存取層,具有以下優點:
然而,儘管三層架構有其優點,在處理複雜業務時,三層架構也可能面臨一些問題。具體有:
具體具體示意如下圖:
隨著業務的不斷複雜化,service層變得越來越龐大,服務之間的參照也變得越來越混亂,這為專案帶來了風險和不確定性。
在三層架構的演化過程中,有時會嘗試引入額外的"Manager"層來管理服務層的功能,但這並不是DDD所倡導的概念。在DDD中,更加關注領域的劃分和內聚,以及如何將領域模型與業務需求對應起來。
一般情況下,三層架構的問題可以通過引入領域驅動設計來解決。在以下內容中,我們將重點放在如何將DDD思想融入現有的三層架構中,以實現更高內聚、更低耦合的程式碼架構。
經過我們的修改,三層架構可以(組合和聚合)演進到右側架構模式,通過這種方式,我們能夠更好地組織和管理程式碼,實現領域內高內聚低耦合的目標。
在進行了基礎程式碼的優化後,接下來我們將探討如何根據領域驅動設計(DDD)思想來優化整體程式碼架構。經過前面的分析,我們大致瞭解了DDD的專案結構,並且明確了每個層次的職責。現在,讓我們更詳細地探討每個層次的程式碼組織。
具體架構類似如下圖:
當將領域驅動設計(DDD)引入到專案架構中,程式碼的組織方式會有所不同,以更好地體現領域的業務邏輯和關係。讓我們詳細解釋每個層次的程式碼組織,為了保證閱讀的連貫性,我們從參照的最低層(domain層)開始說起
Domain層是DDD的核心,它包含了領域物件、值物件、聚合根等,以及領域內的業務邏輯和規則。在這一層,你應該更關注領域的核心業務,讓程式碼更貼近業務現實。以下是一些程式碼組織的思路:
實體和值物件: 領域物件可以分為實體和值物件。實體是有唯一標識的物件,通常代表業務概念;值物件是沒有唯一標識的物件,它們通常用來描述實體的屬性。在這一層,你應該為每個實體和值物件定義其屬性和行為。
聚合和聚合根: 將相關聯的實體和值物件組合成聚合,聚合根是聚合的入口。聚合根負責保持聚合內的一致性,它是領域模型的核心部分。
領域服務: 領域服務用於處理一些領域範圍內的業務邏輯,它們不屬於任何具體的實體或值物件。將這些邏輯封裝在領域服務中可以使領域模型更加清晰。
通用工具類: 通用工具類是一些與領域相關的輔助方法,可以被領域內的多個實體或值物件使用。將通用工具類放在領域層可以更方便地供領域內的實體使用,避免在其他層重複實現。
在domain域內提供,entity(實體),valueobj(值物件),AggregateRoot(聚合根),倉儲介面(IRepository),事件驅動相關(event)
在基礎架構層,我們主要關注與系統的基礎設施和通用功能。這一層包含倉儲模式和介面介面卡,用於封裝資料儲存操作併為領域層提供統一的資料存取介面。通用工具類也可以在這裡定義和實現,為領域層和應用層提供通用的輔助功能。基礎架構層的程式碼組織通常如下:
第三方庫封裝: 如果專案使用了第三方庫或框架,你可以在基礎架構層進行封裝,以便在其他層中更方便地使用。封裝可以包括對第三方庫的初始化、設定以及封裝特定的操作介面。
倉儲介面和介面卡: 在基礎架構層中定義倉儲介面,以及不同資料儲存媒介的介面卡實現。這樣可以將資料存取操作與領域層解耦,同時實現資料儲存的切換。
中介軟體實現: 如果系統使用了中介軟體,如快取、訊息佇列等,你可以在基礎架構層實現中介軟體的具體操作。這有助於將與中介軟體相關的邏輯隔離在基礎架構層中。
事件驅動實現: 如果系統採用了事件驅動的架構,你可以在基礎架構層實現事件的釋出與訂閱機制,以及事件的處理邏輯。
如上圖,使用redis提供快取,使用kafka提供訊息佇列,使用guava提供事件驅動,倉儲層負責實現倉儲功能
Application層用於組合領域內的服務,形成具體的應用用例。它不包含具體的業務邏輯,而是通過呼叫領域內的服務來實現功能。在這一層,你可以有以下的組織方式:
UI層負責展示資料和接收使用者輸入,它不包含業務邏輯,只是通過呼叫Application層來觸發業務流程。在這一層,主要形式有 api,job和檢視頁面等等
當我們將三層架構向DDD演進時,我們逐步重塑我們的程式碼組織,讓領域層成為核心,包含實體、值物件、聚合根和領域服務,以最佳方式捕捉業務邏輯和規則。基礎架構層負責提供通用能力,如倉儲實現、中介軟體封裝等,為領域層提供支援。應用層負責將領域內的服務組合成具體的應用用例,通過呼叫領域服務實現功能。最後,UI層負責與使用者互動,通過呼叫應用層觸發業務流程。這種結構使得不同層次之間的耦合度降低,程式碼變得更清晰、可維護和可延伸。
在我們演進的過程中,重要的是不僅僅是技術層面的變化,更是對於業務的深入理解和把握。DDD不僅僅是一種架構模式,更是一種用於探索和應對複雜業務的方法論。通過將DDD思想融入我們的架構設計中,我們能夠更好地應對日益複雜的業務需求,使得我們的系統更具彈性和適應性,從而為日後面臨複雜的業務奠定基礎。這雖然充滿挑戰,但也必將為我們帶來更大的成長和收穫。
在下一講主要講下DDD在實際落地中碰到的問題和解決方案,歡迎關注。
獨立部落格移至:http://blog.laofu.online/
本文來自部落格園,作者:付威的網路部落格,轉載請註明原文連結:https://www.cnblogs.com/OceanHeaven/p/17652906.html