領域驅動設計模式、原理與實踐

領域驅動設計模式、原理與實踐

《領域驅動設計模式、原理與實踐》是2016年清華大學出版社出版的圖書,作者是Scott Millett。

基本介紹

  • 中文名:領域驅動設計模式、原理與實踐   
  • 作者:(美)Scott Millett、Nick Tune
  • 譯者:蒲成
  • 出版時間:2016年2月1日
  • 出版社清華大學出版社 
  • ISBN:9787302428909
  • 定價:99.8 元
  • 開本:16 開
基本簡介,圖書簡介,目錄,作者薦語,

基本簡介

圖書簡介

本書專注於介紹分解複雜問題空間的原則和實踐,以及構成可維護解空間的實現模式和最佳實踐。你將學習如何通過使用戰術模式構建有效領域模型以及如何通過套用DDD的戰略模式維持其完整性。蒲成 譯

目錄

第Ⅰ部分 領域驅動設計的原則與實踐
第1章 什麼是領域驅動設計 3
1.1 為複雜問題域創建軟體的挑戰 4
1.1.1 未使用通用語言創建的代碼 4
1.1.2 組織結構的缺乏 5
1.1.3 泥球模式將扼殺開發 5
1.1.4 缺乏對問題域的關注 5
1.2 領域驅動設計模式如何管理複雜性 6
1.2.1 DDD的戰略模式 6
1.2.2 DDD的戰術模式 8
1.2.3 問題空間與解空間 9
1.3 領域驅動設計的實踐與原則 10
1.3.1 專注於核心領域 10
1.3.2 通過協作進行學習 10
1.3.3 通過探索和實驗來創建模型 10
1.3.4 通信 11
1.3.5 理解模型的適用性 11
1.3.6 讓模型持續發展 11
1.4 領域驅動設計的常見誤區 12
1.4.1 戰術模式是DDD的關鍵 12
1.4.2 DDD是一套框架 12
1.4.3 DDD是一顆靈丹妙藥 12
1.5 要點 13
第2章 提煉問題域 15
2.1 知識提煉與協作 15
2.1.1 通過通用語言達成共識 16
2.1.2 領域知識的重要性 17
2.1.3 業務分析員的角色 17
2.1.4 一個持續過程 17
2.2 與領域專家一起獲得領域見解 18
2.2.1 領域專家與業務相關人員的對比 18
2.2.2 對於業務的更深刻理解 18
2.2.3 與你的領域專家互動 19
2.3 有效提煉知識的模式 19
2.3.1專注在最有意思的對話上 19
2.3.2從用例開始 19
2.3.3提出有力的問題 20
2.3.4草圖 20
2.3.5CRC卡 21
2.3.6延遲對模型中概念的命名 21
2.3.7行為驅動開發 21
2.3.8快速成型 23
2.3.9查看基於紙面的系統 23
2.4查看現有模型 23
2.4.1理解意圖 24
2.4.2事件風暴 24
2.4.3影響地圖 25
2.4.4理解業務模型 26
2.4.5刻意發現 27
2.4.6模型探討漩渦 27
2.5要點 28
第3章專注於核心領域 31
3.1為何要分解一個問題域 31
3.2如何捕獲問題的實質 32
3.2.1超越需求 32
3.2.2為達成什麼是核心內容的共識而捕獲領域願景 32
3.3如何專注於核心問題 33
3.3.1提煉問題域 34
3.3.2核心領域 35
3.3.3將你的核心領域當作一款產品而非一個項目 36
3.3.4通用域 36
3.3.5支撐域 37
3.4子域如何決定解決方案的形成 37
3.5並非一個系統的所有部分都會經過良好設計 38
3.5.1專注於清晰邊界而非完美模型 38
3.5.2一開始核心領域不必總是需要是完美的 39
3.5.3構建用於替代而非重用的子域 39
3.6如果沒有核心領域怎么辦 39
3.7要點 39
第4章模型驅動設計 41
4.1什麼是領域模型 41
4.1.1領域與領域模型的對比 42
4.1.2分析模型 43
4.1.3代碼模型 43
4.1.4代碼模型是領域模型的主要表現 44
4.2模型驅動設計 44
4.2.1預先設計的挑戰 44
4.2.2團隊建模 46
4.3使用通用語言將分析和代碼模型綁定在一起 47
4.3.1語言的生存周期將大於軟體 48
4.3.2業務語言 48
4.3.3開發人員和業務之間的轉譯 48
4.4基於通用語言進行協作 49
4.4.1通過使用具體示例來定製出語言 50
4.4.2教導你的領域專家專注在問題上而不要跳到解決方案 50
4.4.3塑造語言的最佳實踐 51
4.5如何創建有效的領域模型 52
4.5.1不要讓實情妨礙一個好模型 52
4.5.2僅對相關內容建模 53
4.5.3領域模型都是暫時有用的 53
4.5.4要十分清楚專業術語 54
4.5.5限制你的抽象 54
4.6何時套用模型驅動設計 55
4.6.1如果它不值得花費精力,則不要嘗試對其建模 56
4.6.2專注於核心領域 56
4.7要點 56
第5章領域模型實現模式 59
5.1領域層 59
5.2領域模型實現模式 60
5.2.1領域模型 61
5.2.2事務腳本 64
5.2.3表模組 67
5.2.4活動記錄 67
5.2.5貧血領域模型 67
5.2.6貧血領域模型和函式編程 68
5.3要點 71
第6章使用有界上下文維護領域模型的完整性 73
6.1單個模型的挑戰 74
6.1.1模型的複雜性可能會增加 74
6.1.2多個團隊處理單個模型 74
6.1.3模型語言中的歧義 75
6.1.4領域概念的適用範圍 76
6.1.5集成遺留代碼或第三方代碼 78
6.1.6領域模型並非企業模型 78
6.2使用有界上下文劃分和破除大模型 79
6.2.1定義模型的邊界 81
6.2.2子域和有界上下文之間的差異 84
6.3實現有界上下文 85
6.4要點 88
第7章上下文映射 91
7.1一個現實情況的映射 92
7.1.1技術的現實 92
7.1.2組織的現實 93
7.1.3映射一個相關現實情況 94
7.1.4用X標記核心領域的位置 94
7.2認識有界上下文之間的關係 94
7.2.1防止損壞層 95
7.2.2共享核心 96
7.2.3開放宿主服務 96
7.2.4分道揚鑣 97
7.2.5合作關係 98
7.2.6一種上游/下游關係 98
7.3傳遞上下文映射 99
7.4上下文映射的戰略重要性 100
7.4.1保持完整性 100
7.4.2解決計畫的基礎 101
7.4.3理解所有權和職責 101
7.4.4揭示業務工作流中的混亂區域 101
7.4.5識別非技術障礙 101
7.4.6鼓勵良好的溝通 101
7.4.7幫助加入的新員工 102
7.5要點 102
第8章應用程式架構 103
8.1應用程式架構 103
8.1.1分離應用程式的問題 103
8.1.2從領域的複雜性中進行抽象 104
8.1.3分層架構 104
8.1.4依賴倒置 105
8.1.5領域層 105
8.1.6應用程式服務層 105
8.1.7基礎架構層 106
8.1.8跨層通信 106
8.1.9隔離測試 107
8.1.10不要在有界上下文之間共享數據結構 108
8.1.11應用程式架構與用於有界上下文的架構的對比 109
8.2應用程式服務 110
8.2.1應用程式邏輯與領域邏輯的對比 111
8.2.2定義和公開能力 112
8.2.3業務用例協作 112
8.2.4應用程式服務表示的是用例,而不是創建、讀取、更新和刪除 112
8.2.5作為實現詳情的領域層 113
8.2.6領域報告 113
8.2.7讀取模型與事務模型的對比 113
8.3應用程式客戶端 115
8.4要點 117
第9章團隊開始套用領域驅動設計通常會遇到的問題 119
9.1過分強調戰術模式的重要性 120
9.1.1將相同架構用於所有的有界上下文 120
9.1.2力求戰術模式盡善盡美 120
9.1.3錯誤估計構造塊對於DDD的價值 120
9.1.4專注於代碼而非DDD的原則 121
9.2缺失了DDD的真實價值:協作、通信和上下文 121
9.2.1由於低估上下文的重要性而產生大泥球 122
9.2.2未能成功創建UL將造成歧義和誤解 122
9.2.3由於缺乏協作將只能設計專注於技術的解決方案 123
9.3在不重要的部分花費太多時間 123
9.4簡單問題複雜化 123
9.4.1將DDD原則套用到具有少量業務預期的瑣碎領域 124
9.4.2別將CRUD作為反模式 124
9.4.3將領域模型模式用於每一個有界上下文 124
9.4.4問一問自己:額外的複雜性是否值得 124
9.5低估套用DDD的成本 125
9.5.1嘗試在沒有積極專注的團隊的情況下取得成功 125
9.5.2項目背後沒有領域專家時的協作嘗試 125
9.5.3在非疊代式開發方法中進行學習 125
9.5.4將DDD套用到每一個問題 126
9.5.5為不必要的純粹性而犧牲實用主義 126
9.5.6尋求驗證會浪費精力 126
9.5.7永遠力求代碼之美 127
9.5.8DDD關乎的是提供價值 127
9.6要點 127
第10章套用DDD的原則、實踐與模式 129
10.1推廣使用DDD 129
10.1.1培訓團隊 130
10.1.2與業務人員進行交流 130
10.2套用DDD的原則 131
10.2.1理解願景 131
10.2.2捕獲所需的行為 131
10.2.3理解環境的現實情況 132
10.2.4對解決方案建模 133
10.3探究和實驗 139
10.3.1質疑假設 139
10.3.2建模是一項持續性活動 139
10.3.3不存在錯誤的模型 140
10.3.4靈活的代碼有助於探索發現 140
10.4讓隱式內容變得顯式 140
10.4.1處理歧義 141
10.4.2為事物命名 143
10.5問題解決人先行,技術專家後行 143
10.6如何才能知道我在正確地工作 143
10.6.1好用就足夠了 144
10.6.2實踐、實踐、實踐 144
10.7要點 144
第Ⅱ部分戰略模式:在有界上下文之間通信
第11章有界上下文集成介紹 149
11.1如何集成有界上下文 150
11.1.1有界上下文是獨立自主的 150
11.1.2在代碼層面集成有界上下文的挑戰 151
11.1.3使用物理邊界來強制實現整潔的模型 154
11.1.4集成遺留系統 155
11.2集成分散式有界上下文 158
11.2.1集成用於分散式有界上下文的策略 159
11.2.2資料庫集成 159
11.2.3平面檔案集成 160
11.2.4RPC 161
11.2.5訊息傳遞 162
11.2.6REST 162
11.3DDD使用分散式系統的挑戰 162
11.4分散式事務將損害可擴展性和可靠性 165
11.4.1有界上下文不必彼此保持一致 166
11.4.2最終一致性 166
11.5事件驅動回響式DDD 167
11.5.1展示回響式解決方案的彈性和可擴展性 168
11.5.2異步訊息傳遞的挑戰和取捨 169
11.5.3RPC還有價值嗎 169
11.6SOA和回響式DDD 170
11.6.1將你的有界上下文視作SOA服務 171
  • 11.6.2進一步處理微服務架構 174
  • 11.7要點 175
  • 第12章通過訊息傳遞集成 177
  • 12.1訊息傳遞基礎 178
  • 12.1.1訊息匯流排 178
  • 12.1.2可靠的訊息傳遞 180
  • 12.1.3存儲轉發 180
  • 12.1.4命令和事件 180
  • 12.1.5最終一致性 181
  • 12.2使用NServiceBus構建一個電子商務應用程式 182
  • 12.2.1系統設計 183
  • 12.2.2從Web應用程式傳送命令 187
  • 12.2.3處理命令和發布事件 196
  • 12.2.4使用訊息傳遞網關讓外部HTTP調用變得可靠 203
  • 12.2.5實踐中的最終一致性 211
  • 12.2.6有界上下文會存儲其本地所需的所有數據 212
  • 12.2.7把所有內容都放在UI中 220
  • 12.3維護訊息傳遞應用程式 223
  • 12.3.1訊息版本管理 223
  • 12.3.2監控和擴展 228
  • 12.4將有界上下文與公共傳輸集成 231
  • 12.4.1訊息傳遞橋 232
  • 12.4.2公共傳輸 233
  • 12.5要點 240
  • 第13章通過使用RPC和REST的HTTP來集成 241
  • 13.1為何選用HTTP 242
  • 13.1.1沒有平台耦合 243
  • 13.1.2每個人都理解HTTP 243
  • 13.1.3大量的成熟工具和庫 243
  • 13.1.4內部測試你的API 243
  • 13.2RPC 244
  • 13.2.1在HTTP上實現RPC 244
  • 13.2.2選擇一種RPC風格 259
  • 13.3REST 260
  • 13.3.1深入淺出地解釋REST 260
  • 13.3.2用於有界上下文集成的
  • REST 263
  • 13.3.3維護REST應用程式 297
  • 13.3.4將REST用於有界上下文集成的缺點 298
  • 13.4要點 299
  • 第Ⅲ部分戰術模式:創建有效的領域模型
  • 第14章構造塊領域建模介紹 303
  • 14.1戰術模式 304
  • 14.2對領域建模的模式 305
  • 14.2.1實體 305
  • 14.2.2值對象 308
  • 14.2.3領域服務 310
  • 14.2.4模組 312
  • 14.3生命周期模式 312
  • 14.3.1聚合 312
  • 14.3.2工廠 316
  • 14.3.3存儲庫 316
  • 14.4顯露模式 317
  • 14.4.1領域事件 317
  • 14.4.2事件溯源 319
  • 14.5要點 320
  • 第15章值對象 323
  • 15.1何時使用值對象 324
  • 15.1.1表示描述性的、欠缺身份的概念 324
  • 15.1.2增強明確性 325
  • 15.2定義特徵 327
  • 15.2.1欠缺身份 327
  • 15.2.2基於特性的相等性 327
  • 15.2.3富含行為 331
  • 15.2.4內聚 331
  • 15.2.5不可變 331
  • 15.2.6可組合性 333
  • 15.2.7自驗證 335
  • 15.2.8可測試 338
  • 15.3常見的建模模式 339
  • 15.3.1靜態工廠方法 339
  • 15.3.2微類型 341
  • 15.3.3規避集合 343
  • 15.4持久化 346
  • 15.4.1NoSQL 346
  • 15.4.2SQL 347
  • 15.5要點 354
  • 第16章實體 355
  • 16.1理解實體 356
  • 16.1.1具有身份和連貫性的領域概念 356
  • 16.1.2上下文依賴 356
  • 16.2實現實體 357
  • 16.2.1分配標識符 357
  • 16.2.2將行為推入到值對象和領域服務中 363
  • 16.2.3驗證並強制不變性 365
  • 16.2.4專注於行為,而非數據 368
  • 16.2.5避免“建模現實世界”的謬誤 371
  • 16.2.6分散式設計 371
  • 16.3常見的實體建模原則和模式 373
  • 16.3.1使用規範實現驗證和不變條件 373
  • 16.3.2避免狀態模式;使用顯式建模 376
  • 16.3.3避免將接收器和設定器與備忘錄模式結合使用 379
  • 16.3.4選用無隱藏意外影響的功能 380
  • 16.4要點 382
  • 第17章領域服務 383
  • 17.1理解領域服務 384
  • 17.1.1何時使用領域服務 384
  • 17.1.2領域服務解析 388
  • 17.1.3避免使用貧血領域模型 389
  • 17.1.4與應用程式服務對比 390
  • 17.2利用領域服務 390
  • 17.2.1服務層中 390
  • 17.2.2領域中 391
  • 17.3要點 397
  • 第18章領域事件 399
  • 18.1領域事件模式的實質 400
  • 18.1.1已經發生了的重要領域事件 400
  • 18.1.2回響事件 401
  • 18.1.3可選的異步性 401
  • 18.1.4內部事件與外部事件對比 402
  • 18.2事件處理操作 403
  • 18.2.1調用領域邏輯 403
  • 18.2.2調用應用程式邏輯 404
  • 18.3領域事件的實現模式 404
  • 18.3.1使用.Net框架的事件模型 404
  • 18.3.2使用記憶體中的匯流排 406
  • 18.3.3UdiDahan的DomainEvents靜態類 409
  • 18.3.4返回領域事件 412
  • 18.3.5使用IoC容器作為事件分發器 415
  • 18.4測試領域事件 416
  • 18.4.1單元測試 416
  • 18.4.2套用服務層測試 417
  • 18.5要點 419
  • 第19章聚合 421
  • 19.1管理複雜對象圖形 422
  • 19.1.1選用單一遍歷方向 422
  • 19.1.2合格的關聯關係 424
  • 19.1.3選用ID而不是對象引用 425
  • 19.2聚合 428
  • 19.2.1圍繞領域不變條件進行設計 429
  • 19.2.2高層次的領域抽象 429
  • 19.2.3一致性邊界 429
  • 19.2.4選用較小的聚合 434
  • 19.3定義聚合邊界 435
  • 19.3.1eBidder:線上拍賣案例研究 435
  • 19.3.2與不變條件保持一致 437
  • 19.3.3與事務和一致性保持一致 439
  • 19.3.4忽略用戶界面影響 440
  • 19.3.5避免無用的集合與容器 441
  • 19.3.6不要專注於HAS-A關係 441
  • 19.3.7重構聚合 441
  • 19.3.8滿足業務用例——非現實環境 441
  • 19.4實現聚合 442
  • 19.4.1選擇一個聚合根 442
  • 19.4.2引用其他聚合 446
  • 19.4.3實現持久化 450
  • 19.4.4實現事務一致性 454
  • 19.4.5實現最終一致性 455
  • 19.4.6實現並發性 458
  • 19.5要點 459
  • 第20章工廠 461
  • 20.1工廠的作用 461
  • 20.1.1從構造中分離出套用 462
  • 20.1.2封裝內部事物 462
  • 20.1.3隱藏創建類型的決策 464
  • 20.1.4聚合上的工廠方法 466
  • 20.1.5用於重構的工廠 467
  • 20.1.6務實地使用工廠 469
  • 20.2要點 469
  • 第21章存儲庫 471
  • 21.1存儲庫 471
  • 21.2一種被誤解的模式 473
  • 21.2.1存儲庫是一種反模式嗎 473
  • 21.2.2領域模型和持久化模型之間的區別 474
  • 21.2.3通用存儲庫 475
  • 21.3聚合持久化策略 477
  • 21.3.1使用能在不損壞領域模型的情況下將其映射到數據模型的持久化框架 478
  • 21.3.2使用不能在不影響領域模型的情況下直接映射它的持久化框架 478
  • 21.3.3公共接收器和設定器 479
  • 21.3.4使用備忘錄模式 480
  • 21.3.5事件流 482
  • 21.3.6求真務實 483
  • 21.4存儲庫是一個明確的約定 483
  • 21.5事務管理和工作單元 484
  • 21.6保存或不保存 488
  • 21.6.1持久化追蹤領域對象變更的框架 489
  • 21.6.2必須將變更顯式保存到聚合 490
  • 21.7充當防止損壞層的存儲庫 491
  • 21.8存儲庫的其他職責 491
  • 21.8.1實體ID生成 492
  • 21.8.2集合匯總 494
  • 21.8.3並發性 494
  • 21.8.4審計追蹤 498
  • 21.9存儲庫反模式 498
  • 21.9.1反模式:不要支持即席查詢 498
  • 21.9.2反模式:延遲載入是一種設計異味 499
  • 21.9.3反模式:不要為了報告需要而使用存儲庫 499
  • 21.10存儲庫實現 499
  • 21.10.1持久化框架可以在不損壞領域模型的情況下將其映射到數據模型 500
  • 21.10.2持久化框架不能在不損壞領域模型的情況下直接映射領域模型 550
  • 21.11要點 586
  • 第22章事件溯源 587
  • 22.1將狀態存儲為快照的限制 588
  • 22.2通過將狀態存儲為事件流來獲得競爭優勢 589
  • 22.2.1時態查詢 589
  • 22.2.2投影 590
  • 22.2.3快照 591
  • 22.3源自事件的聚合 591
  • 22.3.1構造 592
  • 22.3.2持久化與再融合 596
  • 22.4構建一個事件存儲 603
  • 22.4.1設計一種存儲格式 604
  • 22.4.2創建事件流 605
  • 22.4.3附加到事件流 606
  • 22.4.4查詢事件流 606
  • 22.4.5添加快照支持 607
  • 22.4.6管理並發性 609
  • 22.4.7一個基於SQLServer的事件存儲 613
  • 22.4.8構建你自己的事件存儲是一個好主意嗎 619
  • 22.5使用專門構建的EventStore 619
  • 22.5.1安裝GregYoung的EventStore 619
  • 22.5.2使用C#客戶端庫 620
  • 22.5.3運行時態查詢 624
  • 22.5.4創建投影 627
  • 22.6使用事件溯源的CQRS 629
  • 22.6.1使用投影創建視圖快取 630
  • 22.6.2CQRS和事件溯源協作 630
  • 22.7簡要複述事件溯源的好處 631
  • 22.7.1競爭性業務優勢 631
  • 22.7.2專注於表述性行為的聚合 631
  • 22.7.3簡化的持久化 632
  • 22.7.4更好的調試 632
  • 22.8衡量事件溯源的代價 632
  • 22.8.1版本控制 632
  • 22.8.2要學習的新概念和要磨練的技能 632
  • 22.8.3需要學習和掌握的新技術 633
  • 22.8.4大量的數據存儲需求 633
  • 22.9額外的學習資源 633
  • 22.10要點 633
  • 第Ⅳ部分有效應用程式的設計模式
  • 第23章應用程式用戶界面的架構設計 637
  • 23.1設計考量 638
  • 23.1.1占有式UI與構成式UI的對比 638
  • 23.1.2HTMLAPI與數據API的對比 640
  • 23.1.3客戶端與伺服器端聚合/協作對比 641
  • 23.2示例1:用於非分散式有界上下文的一個基於HTMLAPI的、伺服器端的UI 643
  • 23.3示例2:用於分散式有界上下文的一個基於數據API的客戶端UI 650
  • 23.4要點 658
  • 第24章CQRS:一種有界上下文的架構 659
  • 24.1為兩個上下文維護單個模型的挑戰 660
  • 24.2用於複雜有界上下文的一種更好的架構 661
  • 24.3命令端:業務任務 662
  • 24.3.1顯式建模意圖 662
  • 24.3.2不受展現干擾所影響的模型 663
  • 24.3.3處理業務請求 665
  • 24.4查詢端:領域報告 665
  • 24.4.1直接映射到數據模型的報告 666
  • 24.4.2從領域事件中構建的具體化視圖 667
  • 24.5對CQRS的誤解 668
  • 24.5.1CQRS很難 668
  • 24.5.2CQRS是最終一致的 668
  • 24.5.3模型需要源自事件 669
  • 24.5.4命令應該是異步的 669
  • 24.5.5CQRS僅適用於訊息傳遞系統 669
  • 24.5.6需要將CQRS用於領域事件 669
  • 24.6可以擴展應用程式的模式 669
  • 24.6.1擴展讀取端:一個最終一致的讀取模型 670
  • 24.6.2擴展寫入端:使用異步命令 672
  • 24.6.3對一切進行擴展 673
  • 24.7要點 674
  • 第25章命令:用於處理業務用例的應用程式服務模式 677
  • 25.1區分應用程式邏輯和
  • 領域邏輯 678
  • 25.1.1應用程式邏輯 678
  • 25.1.2來自應用程式服務角度的領域邏輯 690
  • 25.2應用程式服務模式 690
  • 25.2.1命令處理程式 690
  • 25.2.2發布/訂閱 694
  • 25.2.3請求/回復模式 696
  • 25.2.4async/await 698
  • 25.3測試應用程式服務 699
  • 25.3.1使用領域專業術語 699
  • 25.3.2測試儘可能多的功能 700
  • 25.4要點 702
  • 第26章查詢:領域報告 703
  • 26.1有界上下文中的領域報告 704
  • 26.1.1從領域對象中派生報告 704
  • 26.1.2直接訪問數據存儲 710
  • 26.1.3從事件流構建投影 716
  • 26.2跨有界上下文的領域報告 723
  • 26.2.1複合UI 723
  • 26.2.2單獨的報告上下文 724
  • 26.3要點 726

作者薦語

Scott Millett是Iglu.com的IT總監,從1.0版本開始就使用.NET工作了。他在2010年和2011年獲得了ASP.NET MVP,並且還著有《ASP.NET設計模式》和《精通.NET企業項目開發:最新的模式、工具與方法》。
Nick Tune是用技術、協作和領域驅動設計為複雜業務問題提供解決方案的軟體開發者。通過開發目標宏偉的產品以及與充滿熱情的人一起工作,他在尋求不斷地自我提升。

相關詞條

熱門詞條

聯絡我們