SlideShare une entreprise Scribd logo
1  sur  33
DDD引導
大綱
• 什麼是DDD?
• 領域分析
• Entity / Value Object
• Repository
• 事件驅動: Domain Driven
• 實務探討
什麼是DDD?
• DDD全名是Domain Driven Development(領域驅動開發),它具有以
下特性:
• 從領域的角度去分析系統
• 緊密結合客戶的領域專家(Domain Expert)和開發團隊
• 是一套完整的開發方法
領域(Domain)
• 軟體系統存在的目的在於解決特定問題
• 在解決問題之前,要先瞭解問題相關的專業知識
• 在現實世界中,專業知識體都可以稱之為 – 領域
• 瞭解相關知識後,模型化(Modeling)知識;繪出領域內部實體之間關聯性的
輪廓
採用DDD會有什麼好處
• 消除客戶/BA/PM/開發人員溝通的隔閡
• 程式碼即文件
• 減緩系統老化的時間
DDD的兩個部份: 戰略 & 戰術
• DDD在戰略上採用:
• 通用語言
• 限界文本(Bounded Context)
• DDD在戰術上採用:
• 實體(Entity)
• 值物件(Value Object)
• 領域服務(Domain Service)
• 倉儲(Repository)
• 領域事件(Domain Event)
• 防腐層(Anti-Disruption)
戰略的意義
• 在未開發的前期,先行分析系統和真正要解決的問題
• 建構系統組成的輪廓,以便後續開發時期的規劃和設計
• 及早瞭解各個子系統(模組)之間的關聯性
戰術的意義
• 讓程式碼的語意更加的豐富,實際落實:程式碼即文件的精神
• 避免發生資料導向(Data Driven)的設計模式
• 建構開發的風格(Style)一致性
領域分析
• 從使用者/領域專家所收集來的需求資訊,進行組織&歸納,最終將
未來要開發的系統概念化成一個個領域
• 分析的工作可能無法在第一次就完成,需要反覆和使用者/領域專
家確認多次後才能定案
• 在開發的過程中,也有可能發覺到一開始所分析的領域需要被刪減
/合併/增加,這些都是極有可能發生的
• 在眾多已被分析出來的領域中挑選其中一個作為核心領域(Core);
該領域是此產品最具競爭力的領域,需要傾全力開發
分析的過程
• 在與使用者/領域專家開會及討論需求的過程中,需要有意識的建
構出 – 通用語言
通用語言
• 專案失敗的原因之一: 溝通
• 通用語言:
• 團隊對於某件事物的定義是一致,並且有共識的
• DDD採用通用語言來消除溝通的隔閡
• 程式碼的命名需符合通用語言,甚至就連物件彼此協作的行為也需
要符合通用語言
準備進入開發
• 在進入開發階段的最後一哩,是對更貼近系統設計面的分析,這個
時候要用到的就是-限界文本
限界文本(Bounded Context)
• 針對領域而規劃的系統模組 or 子系統
• 若說領域是針對現實世界,那麼限界文本就是朝向軟體結構的世界
• 最佳實務: 一個領域一個限界文本
(實務: 一個領域會有多個限界文本,某些限界文本在特殊情況下會
跨多個領域)
• 限界文本之間具有: 上-下游 的關連性
關鍵概念
• DDD是開發方法,本身並沒有對於程式語言的設限,可以使用任意語
言去實現
• DDD本身並不是架構,意即開發人員可以將其套用在任何架構上,諸
如: N-Layer/Tier, Onion … 等
• 限界文本可以彼此獨立地採用各種架構和技術去實做
實體(Entity) / 值物件(Value Object)
• 實體/值物件是DDD戰術中最重要的兩個項目
• 實體:
• 每個物件都有識別碼(ID)
• 系統會追蹤它生命週期內的所有狀態的變化
• 值物件:
• 物件無識別碼(ID),系統以它擁有的屬性值組(Set)來比較兩個值物件是否相
同
• 當某個屬性值異動時,它就是一個新的值物件;已經與舊的不同
細說實體
• 在現實世界中,某些東西需要被追蹤它的變化,為了要能夠追蹤它
的變化,就需要用識別碼(ID)來快速地區分不同的東西
• 容易與值物件混淆,在茫茫需求之中難以識別何者該為實體?何者
為值物件?
• 資料庫的綱要(Schema)設計,不建議採用實體為資料表的映射;應該
是要使用值物件
• 相同名稱的實體在不同限界文本中是完全不相干且不同含義的
不同限界文本的實體資料同步
• 雖然相同名稱的實體在不同限界文本中,但是其部份屬性的資料是
相同甚至兩個物件的屬性完全相同
• 同步限界文本的兩個具有相同屬性的實體可以採用:
• 防腐層 – 當實體更新後,呼叫另一個限界文本的防腐層進行資料同步
• 領域事件 - 實體更新後發出領域事件,另一個限界文本訂閱此事件,並進行
資料的同步
細說值物件
• 值物件在領域中,它是一種度量衡單位會使用到的物件,它不需要
被追蹤,因此,也就不需要識別碼
• 實例:
住址, 游戲角色屬性值…
• 值物件在賦值給變數方面就如同在程式碼中對一個主要型別的變
數進行賦值一樣:
int a = 10;
這個10就如同一個值物件,當程式碼要賦與a變數另一個值時:
a = 20;
可將值物件看作如同上例的常數值那般,每個值彼此獨立,當內容
改變,就是一個全新的值物件
實體與值物件如何辨識
• 在一段需求描述中,可以從中將重要的關鍵名詞挑出作為候選人,
接著進行下述假設問題:
• 它需要被追蹤嗎?
• 屬性值的不同代表著是另一個不同的東西?
• 這個名詞是一種度量衡的單位?
• 上述假設性問題,如果答案是: false, true , true 那麼它必定為值物
件
不建議將實體作為參數
• 不使用實體作為參數可以避免領域知識洩漏到外層,進而導致商業
邏輯散佈在各個地方,造成維護的複雜度提升
• 採用值物件作為參數傳遞,是較為推荐的做法
聚合
• 在領域中,會探討到某些場景活動,而這些場景活動中參與者會由
其特性而被摘錄成為實體或是值物件。
• 場景活動映射到DDD中,即為: 聚合
• 聚合是由一個實體(註: 亦名為根實體)所擔任,在這個實體中會有許
多的實體與值物件組合
• 聚合無法直接存取另一個聚合中的實體,需透過這個聚合的根實體
來達成
貧血/富血物件
• 當一個類別只有Get/Set這些屬性而沒有方法,則稱其為貧血物件;
反之,則為富血物件
• DDD傾向採用富血物件,因為使用貧血物件很容易造成維護上的困
難,主要在於無法完整地使用一個物件表達通用語言中所描述的概
念
• 一個只有屬性的物件,其處理的邏輯和方法勢必是被拆離到另一個
物件身上,如此一來,想要瞭解程式碼背後的知識就需要自行在腦
中拼湊它完整的長相
領域服務(Domain Service)
• 為了能夠充份表達通用語言中所描述的內容,實體上某些方法並不
適合放在該實體身上
• 例: 跨聚合的兩個實體進行協作
• 領域服務的存在不是為了將實體/值物件身上的方法都移轉到它身
上,它是一個迫不得已的存在
• 領域服務建議採用無狀態
• 防腐層中的物件多為領域服務(Proxy)
倉儲(Repository)
• 資料庫存在的目的在於將系統中的物件當前的狀態保存下來,這是
因為應用程式伺服器的記憶體有限,而物件數量無限
• 實體和值物件的狀態會被保存到資料庫中,並且使用倉儲物件將其
還原回到被保存之前的狀態
• 一個實體會由其它實體和值物件所構成,因此其結構十分的複雜,
如果沒有一個物件負責承擔還原實體/值物件的工作,會造成系統
維護的複雜度
論資料庫系統
• 現行資料庫已不在以關聯式資料庫為唯一選擇,其餘還有許多
NoSQL可以選擇
• NoSQL資料可分為四大類:
• Key/Value Pair
• Document
• Column
• Graph
• 每個限界文本可依儲存的模式和成本進行資料庫系統選擇上的考
量
倉儲物件的歸屬
• 在多層(N-Layer)架構中,倉儲物件歸屬於領域層
• 倉儲物件本身的工作是還原實體/值物件,因此,它身上會有: 如何建
構實體,這些相關的底層知識
• 在採用洋蔥(Onion)架構時,可以只在領域層定義倉儲物件的介面,
實做類別則是放在基礎建設層(Infrastructure)
• 這是因為洋蔥架構希望領域層不要有太多的框架/類別庫汙染
工廠與倉儲
• 與倉儲相對映的就屬工廠了;工廠是常見的設計模式之一
• 當應用層的物件需要建構一個新的實體時,若此實體極為複雜,則
它需要一個工廠將其建構的細節進行封裝
• 反之,若該實體已經存在過系統中,只是當前被序列化到資料庫中,
則需要改用倉儲來將其還原
• 兩者近乎等價,只是使用時機不同
事件驅動: Domain Event
• 領域事件在DDD原提出者的書中並沒有太多的著墨,但其後續以它
所發展出事件驅動的架構風格卻蓬勃發展
• 領域事件所代表的是實體的狀態變化
一個方法的二分法
• 程式語言中的函數可以被二分為:
• 查詢(Query)
• 命令(Command)
• 查詢本身並不會改變問題的答案,因此,這類型的方法都具有冪等
性
• 命令會更動到實體的屬性,因此,實體會在其命令型的方法執行完
畢之前,發出領域事件
事件驅動
• 事件驅動的設計方式是一種古老的設計手法
• 作業系統就是採用這種架構
• Web系統從前沒有這麼複雜的系統架構需求,但是在現代,它變得極
為複雜,而事件驅動是偏向人類思考和認知世界的模式,有助於對
抗系統設計的複雜性
• 當實體A發出領域事件後,對這個事件感興趣的其它實體會接收並
做一系列相關聯的處理,但是當初發出事件實體A並不需要知道其
它實體是怎麼運作的
• 鬆耦合
CQRS/CQS
• CQRS/CQS是常見的事件驅動架構,該架構對於高流量型系統極為
適合
• CQRS/CQS將使用者的請求區分成:查詢(Query)和命令(Command),
並且將其拆分成兩個不同處理的子系統
• CQRS/CQS在命令方面的請求採用最終一致性的策略,以期能夠負
擔瞬間暴衝的使用者請求
• 命令與查詢分別有各自的資料庫系統,但命令執行完畢之後會同步
兩個資料庫
• 查詢所使用的資料庫,其綱要採用非正規化的使用者查詢導向設計
領域事件與CQRS
• DDD可選用CQRS作為其架構,當決定採用CQRS之後,領域事件的地
位就會大幅上升
• 當命令請求抵達應用層之後,應用層物件會使用倉儲物件來取得實
體/值物件,接著呼叫實體上相應的命令方法,而實體的命令方法在
執行結束之前會發出領域事件
• 該領域事件會由事件處理器(Hanlder)進行處理(例:儲存值到資料庫)
• 事件處理器會再發出另一個領域事件給查詢子系統中可以處理此事件的
處理器
• 查詢子系統的事件處理器會將收到的事件資料進行再處理,爾後儲存到查
詢所使用的資料庫中
領域事件的實務
• 限界文本之間相互獨立,但會彼此會有溝通的需求,除了可以藉防
腐層之外,還可以使用領域事件配合Service Bus來達成
• 領域事件可以讓各個模組和限界文本之間保持鬆耦合
• 為避免領域事件散射的狀況太過發散,建議在設計領域事件之間有
個團隊的設計會議,規劃並避免發散

Contenu connexe

Similaire à DDD引導

[DDD] 快快樂樂學DDD
[DDD] 快快樂樂學DDD[DDD] 快快樂樂學DDD
[DDD] 快快樂樂學DDDClark
 
2020 11-27 Taiwan DDD Conference
2020 11-27 Taiwan DDD Conference2020 11-27 Taiwan DDD Conference
2020 11-27 Taiwan DDD ConferenceGuan-Rong Huang
 
實踐 Clean Architecture(實作高可用性的軟件架構)
實踐 Clean Architecture(實作高可用性的軟件架構)實踐 Clean Architecture(實作高可用性的軟件架構)
實踐 Clean Architecture(實作高可用性的軟件架構)Gelis Wu
 
[Presales Training]05 方案 项目管理解决方案
[Presales Training]05 方案   项目管理解决方案[Presales Training]05 方案   项目管理解决方案
[Presales Training]05 方案 项目管理解决方案Jimmy Chang
 
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案 Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案 drewz lin
 
Hadoop的典型应用与企业化之路 for HBTC 2012
Hadoop的典型应用与企业化之路 for HBTC 2012Hadoop的典型应用与企业化之路 for HBTC 2012
Hadoop的典型应用与企业化之路 for HBTC 2012James Chen
 
Android裝置開發過程的軟硬整合關鍵及挑戰
Android裝置開發過程的軟硬整合關鍵及挑戰Android裝置開發過程的軟硬整合關鍵及挑戰
Android裝置開發過程的軟硬整合關鍵及挑戰tick
 
Android开发培训 单元1
Android开发培训 单元1Android开发培训 单元1
Android开发培训 单元1longqi293
 
Drupal7第一堂
Drupal7第一堂Drupal7第一堂
Drupal7第一堂Hen Chen
 
Nb的敏捷
Nb的敏捷Nb的敏捷
Nb的敏捷oulan
 
Android 基礎開發課程
Android 基礎開發課程Android 基礎開發課程
Android 基礎開發課程Duran Hsieh
 
高科技產業資料分析解決方案 Hare DB
高科技產業資料分析解決方案 Hare DB高科技產業資料分析解決方案 Hare DB
高科技產業資料分析解決方案 Hare DBEtu Solution
 
Android开发基础
Android开发基础Android开发基础
Android开发基础ykdsg
 
2019-03-13-ddd taiwan-community-iddd-studygroup-2nd
2019-03-13-ddd taiwan-community-iddd-studygroup-2nd2019-03-13-ddd taiwan-community-iddd-studygroup-2nd
2019-03-13-ddd taiwan-community-iddd-studygroup-2ndFong Liou
 
姚彤 从360手机卫士的研发经历看大型移动应用开发
姚彤 从360手机卫士的研发经历看大型移动应用开发姚彤 从360手机卫士的研发经历看大型移动应用开发
姚彤 从360手机卫士的研发经历看大型移动应用开发Trinea Trinea
 
深入淺出Node.JS
深入淺出Node.JS深入淺出Node.JS
深入淺出Node.JS國昭 張
 
Realtime analytics with Flink and Druid
Realtime analytics with Flink and DruidRealtime analytics with Flink and Druid
Realtime analytics with Flink and DruidErhwen Kuo
 
Top100summit前端的云时代支付宝前端平台架构 王保平
Top100summit前端的云时代支付宝前端平台架构  王保平Top100summit前端的云时代支付宝前端平台架构  王保平
Top100summit前端的云时代支付宝前端平台架构 王保平drewz lin
 

Similaire à DDD引導 (20)

[DDD] 快快樂樂學DDD
[DDD] 快快樂樂學DDD[DDD] 快快樂樂學DDD
[DDD] 快快樂樂學DDD
 
2020 11-27 Taiwan DDD Conference
2020 11-27 Taiwan DDD Conference2020 11-27 Taiwan DDD Conference
2020 11-27 Taiwan DDD Conference
 
實踐 Clean Architecture(實作高可用性的軟件架構)
實踐 Clean Architecture(實作高可用性的軟件架構)實踐 Clean Architecture(實作高可用性的軟件架構)
實踐 Clean Architecture(實作高可用性的軟件架構)
 
[Presales Training]05 方案 项目管理解决方案
[Presales Training]05 方案   项目管理解决方案[Presales Training]05 方案   项目管理解决方案
[Presales Training]05 方案 项目管理解决方案
 
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案 Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案
Top100summit东软 孙广宇-uni sdp基于html5构建的跨平台的统一智能设备解决方案
 
Hadoop的典型应用与企业化之路 for HBTC 2012
Hadoop的典型应用与企业化之路 for HBTC 2012Hadoop的典型应用与企业化之路 for HBTC 2012
Hadoop的典型应用与企业化之路 for HBTC 2012
 
Android裝置開發過程的軟硬整合關鍵及挑戰
Android裝置開發過程的軟硬整合關鍵及挑戰Android裝置開發過程的軟硬整合關鍵及挑戰
Android裝置開發過程的軟硬整合關鍵及挑戰
 
Web Engineering
Web EngineeringWeb Engineering
Web Engineering
 
Android开发培训 单元1
Android开发培训 单元1Android开发培训 单元1
Android开发培训 单元1
 
Drupal7第一堂
Drupal7第一堂Drupal7第一堂
Drupal7第一堂
 
Nb的敏捷
Nb的敏捷Nb的敏捷
Nb的敏捷
 
Nb的敏捷
Nb的敏捷Nb的敏捷
Nb的敏捷
 
Android 基礎開發課程
Android 基礎開發課程Android 基礎開發課程
Android 基礎開發課程
 
高科技產業資料分析解決方案 Hare DB
高科技產業資料分析解決方案 Hare DB高科技產業資料分析解決方案 Hare DB
高科技產業資料分析解決方案 Hare DB
 
Android开发基础
Android开发基础Android开发基础
Android开发基础
 
2019-03-13-ddd taiwan-community-iddd-studygroup-2nd
2019-03-13-ddd taiwan-community-iddd-studygroup-2nd2019-03-13-ddd taiwan-community-iddd-studygroup-2nd
2019-03-13-ddd taiwan-community-iddd-studygroup-2nd
 
姚彤 从360手机卫士的研发经历看大型移动应用开发
姚彤 从360手机卫士的研发经历看大型移动应用开发姚彤 从360手机卫士的研发经历看大型移动应用开发
姚彤 从360手机卫士的研发经历看大型移动应用开发
 
深入淺出Node.JS
深入淺出Node.JS深入淺出Node.JS
深入淺出Node.JS
 
Realtime analytics with Flink and Druid
Realtime analytics with Flink and DruidRealtime analytics with Flink and Druid
Realtime analytics with Flink and Druid
 
Top100summit前端的云时代支付宝前端平台架构 王保平
Top100summit前端的云时代支付宝前端平台架构  王保平Top100summit前端的云时代支付宝前端平台架构  王保平
Top100summit前端的云时代支付宝前端平台架构 王保平
 

Plus de 國昭 張

20190126 ddd-meetup1
20190126 ddd-meetup120190126 ddd-meetup1
20190126 ddd-meetup1國昭 張
 
事件風暴-設計衝刺
事件風暴-設計衝刺事件風暴-設計衝刺
事件風暴-設計衝刺國昭 張
 
事件風暴-領域建模
事件風暴-領域建模事件風暴-領域建模
事件風暴-領域建模國昭 張
 
Scrum essential
Scrum essentialScrum essential
Scrum essential國昭 張
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討國昭 張
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0國昭 張
 
Redux+react js
Redux+react jsRedux+react js
Redux+react js國昭 張
 
前端自動化工具
前端自動化工具前端自動化工具
前端自動化工具國昭 張
 
例外處理與單元測試
例外處理與單元測試例外處理與單元測試
例外處理與單元測試國昭 張
 
ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享國昭 張
 
ASP.Net MVC Framework
ASP.Net MVC FrameworkASP.Net MVC Framework
ASP.Net MVC Framework國昭 張
 
SQL Server效能調校
SQL Server效能調校SQL Server效能調校
SQL Server效能調校國昭 張
 
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹NoSQL-MongoDB介紹
NoSQL-MongoDB介紹國昭 張
 

Plus de 國昭 張 (20)

20190126 ddd-meetup1
20190126 ddd-meetup120190126 ddd-meetup1
20190126 ddd-meetup1
 
事件風暴-設計衝刺
事件風暴-設計衝刺事件風暴-設計衝刺
事件風暴-設計衝刺
 
事件風暴-領域建模
事件風暴-領域建模事件風暴-領域建模
事件風暴-領域建模
 
單元測試
單元測試單元測試
單元測試
 
Docker實務
Docker實務Docker實務
Docker實務
 
Scrum essential
Scrum essentialScrum essential
Scrum essential
 
Docker進階探討
Docker進階探討Docker進階探討
Docker進階探討
 
Vue
VueVue
Vue
 
Docker基礎
Docker基礎Docker基礎
Docker基礎
 
前端測試
前端測試前端測試
前端測試
 
Asp.net core v1.0
Asp.net core v1.0Asp.net core v1.0
Asp.net core v1.0
 
Redux+react js
Redux+react jsRedux+react js
Redux+react js
 
React js
React jsReact js
React js
 
前端自動化工具
前端自動化工具前端自動化工具
前端自動化工具
 
例外處理與單元測試
例外處理與單元測試例外處理與單元測試
例外處理與單元測試
 
ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享ASP.Net WebAPI經驗分享
ASP.Net WebAPI經驗分享
 
ASP.Net MVC Framework
ASP.Net MVC FrameworkASP.Net MVC Framework
ASP.Net MVC Framework
 
SQL Server效能調校
SQL Server效能調校SQL Server效能調校
SQL Server效能調校
 
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹NoSQL-MongoDB介紹
NoSQL-MongoDB介紹
 
Linq初階
Linq初階Linq初階
Linq初階
 

DDD引導