前面我們花了14篇的文章來給大家介紹經典DDD的概念、架構和實踐。這篇文章我們來做一個完整的總結,另外生成一個Api接口文檔。
一.DDD解決傳統的開發的幾大問題:
- 沒有描述需求的設計模型;而是直接通過數據庫表的方式體現,也就是需求與設計是脫節的。
- 編碼的架構也沒有與設計和需求對應起來。
- 業務邏輯與技術混在一起;業務邏輯可能直接調用的數據訪問,這樣把業務邏輯與數據訪問的技術混在一起。
- 開發沒有層次感和節奏感;系統沒有一個統一的約束,開發人員沒有一個統一的節奏,這主要體現在隨意的編碼。
- Bug 定位困難:當系統出現業務異常行為時,無法快速准確的定位出現問題的位置,因為系統不同開發人員的代碼放置隨意性。
- 需求變更響應緩慢:在大型的系統或產品中,當需要增加功能或修改現有功能時,因為代碼架構的隨意性,可能會出現改了功能可能會影響到其他的功能,造成系統極不穩定。
解決軟件設計與開發問題的套路就是領域驅動設計(簡稱 DDD)。DDD 這個套路能夠靈活解決以上的問題,為我們提供一個好的設計、架構以及高質量的代碼。
二.DDD解決之道:
DDD 方法首先是需要將需求分析后,形成一個反應需求的領域模型。領域模型就是大家平常理解的類、類的屬性、類之間的關系等。當然在 DDD 中,為了更好的將領域模型反應需求,對類、類的屬性、類之間的關系等有一些模式的指導。比如類的屬性可能是一般屬性,也可能是值對象;比如有關系的類之間是否是代表一個整體概念、有相同生命周期、需要統一持久化等。所以我們的領域模型除了能夠跑通需求外,還要考慮聚合根、實體、值對象、聚合等概念的應用,這樣領域模型的設計才能更好的反應需求,也能夠更好的將設計對應成有約束力的代碼。另外 DDD 也提供了大量模式,告訴我們應該如何編寫對應設計的代碼,能夠將我們的代碼真正映射到設計;如何進行業務邏輯與持久化機制的剝離;如何進行更好的架構設計等。
1.DDD能應對復雜性:系統復雜性主要體現在三個方面。一是技術維度,有業務代碼的實現、有與數據庫或其他持久化存儲交互的實現、有消息隊列的實現、有身份驗證與授權的實現、有 WebAPI 暴露的實現等;二是業務維度,有太多的模塊和功能需要去做;三是時間維度,需要快速的開發,快速的響應需求的變更,快速的修正 Bug。DDD應對復雜性主要通過三個方面:
- a. 技術維度:通過合理的架構分層,能夠讓每層關注自己的事情,比如領域層只關注業務邏輯的事情,倉儲實現層只關注持久化數據與查詢的事情,應用服務層只關注協調領域層與倉儲實現層完成用例的事情,接口層只關注暴露給前端的事情。
- b. 業務維度:通過將大系統划分成多個界限上下文,可以讓不同團隊和不同人只關注當前上下文的開發。在當前界限上下文中的領域層、倉儲實現層、應用服務層、接口層都與其他界限上下文獨立開來,這樣可以專注開發,並且在修改代碼與發布產品時,影響面較小。
- c. 時間維度:通過敏捷式迭代快速驗證,快速修正。
2.高效掌握DDD:
a. 熟悉概念:充分熟悉前面文章介紹的界限上下文、實體、值對象、領域服務、聚合、聚合根、倉儲、應用服務、接口等。
b. 熟悉架構:充分熟悉前面文章介紹的經典DDD的架構。
c. 實踐:前面文章從產品、經銷商、訂單三個界限上下文分析了需求、建立了領域模型、通過經典DDD架構實現了代碼,需要你在實際項目中靈活的運用。
三.接口文檔的生成
當我們已經做好了所有的接口后,需要生成WebApi在線的接口文檔,便於前端人員進行查看與使用。.net core webapi中使用Swagger生成接口文檔。
1.在WebApi項目中引入Nuget包:Swashbuckle.AspNetCore。
2.在WebApi項目屬性的生成中,勾選“XML 文檔文件”。此目的是可以包括WebApi中每個接口的注釋。
3.在WebApi Startup.cs文件的ConfigureServices方法中,添加如下的代碼:
//swagger接口文檔的信息 services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1", Title = "產品界限上下文接口文檔", Description = "包括產品界限上下文所有接口的描述", Contact =new Contact {Name="曹劍",Email="malaoko@hotmail.com"} }); //使用Xml文檔中接口的注釋 var basePath = ApplicationEnvironment.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "Product.WebApi.xml"); c.IncludeXmlComments(xmlPath); });
4.在Configure方法中,添加如下的代碼:
//制定swagger接口文檔的訪問url路徑信息 app.UseSwagger(); app.UseSwaggerUI(p => { p.SwaggerEndpoint("/swagger/v1/swagger.json", "Product接口"); });
5.修改Properties下的launchSettings.json文件中的兩個launchUrl的值都改為swagger,這樣在打開這個WebApi時,自動跳轉到swagger幫助文件:
"profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "Product.WebApi": { "commandName": "Project", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5000" } }
6.訪問時,最終的效果如下圖:
7.在點擊每個接口時,可以看到詳細的調用說明:
本系列的文章就到這里,這個系列的文章主要是講解了經典DDD,關於CQRS DDD與微服務,可以繼續關注我們后續的系列文章,也可以加入QQ群或關注我們的
微信公眾號。在后續CQRS與微服務的內容中,我們將實現如下的架構
微服務架構:
CQRS架構:
QQ討論群:309287205
DDD實戰進階視頻請關注微信公眾號: