Slide 1

Slide 1 text

從領域知識到 設計軟體架構 Sandy / James Wang

Slide 2

Slide 2 text

講者簡介 Sandy • 目前任職於金融業資訊部門,擔任開發部門小組長,致 力在公司中推廣及應用 DDD。 James Wang • 喜歡學習的 Programmer,讓自己能夠持續交付有品質 有價值的軟體給客戶。

Slide 3

Slide 3 text

大家會遇到的問題 A big ball of mud is a haphazardly structured, sprawling, sloppy, duct-tape- and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. —Brian Foote and Joseph Yoder

Slide 4

Slide 4 text

大泥球 • 架構設計不良,缺乏前期設計,使系統架構崩潰埋下隱患。 • 業務成長或需求不斷變化,架構變化過晚,使系統越來越複雜化。 根源: • 將程式依據職責擺放。 解決方法:

Slide 5

Slide 5 text

分層設計 User Interface Application Domain

Slide 6

Slide 6 text

只有分層還不夠

Slide 7

Slide 7 text

只有分層還不夠 + 垂直切割

Slide 8

Slide 8 text

Domain Model B 你還需要 Domain User Interface Application Domain Domain Model A User Interface Application Domain Domain Model C User Interface Application Domain 領域分割 技 術 分 割

Slide 9

Slide 9 text

你還需要 Domain – BUT! Domain Model B User Interface Application Domain Domain Model A User Interface Application Domain Domain Model C User Interface Application Domain 1. 我們如何切分 Domain? 2. Domain 間如何 溝通? 3. 如何設計單 一 Domain? 1. 如何切分? 3. 如何設計? 2. 如何溝通?

Slide 10

Slide 10 text

我們如何切分 Domain?

Slide 11

Slide 11 text

我們如何切分 Domain?- DDD 戰略 • DDD 的戰略設計中,能夠幫助我們 從業務角度出發,建立統一語言及 領域模型,劃分領域邊界,並找出 業務領域的核心。 • 有兩個常見的技法 o Event Storming o Domain Storytelling。

Slide 12

Slide 12 text

Event Storming • Event Storming 以工作坊的形式來促進人們 彼此互動、探索複雜的業務領域。 • 在實作上,常會使用大白板及不同顏色的便利 貼,來營造讓參與者間能互動討論的氛圍,並呈 現整個業務流程的事件和相關資訊。

Slide 13

Slide 13 text

利用 Event Storming 尋找邊界 • 可以透過進行 Big Picture 層級的 Event Storming,來探索領域邊界, 例如尋找業務流程中的關鍵事件(Pivotal Event)。 圖片來源:Introducing EventStorming (https://leanpub.com/introducing_eventstorming)

Slide 14

Slide 14 text

商業全貌 - 以房貸商業流程為例 顆粒非常的粗的商業流程。

Slide 15

Slide 15 text

浮現商業結構 Business Flow(Time) Emerging Bounded Contexts (Sub-Domain)

Slide 16

Slide 16 text

浮現商業結構 - 以房貸商業流程為例 Pivotal Events Swimlanes 相同流程,不同人分析,結果可能不同; 或越深入了解領域知識,會持續調整邊界。 所以切分商業流程沒有絕對,以團隊內當下共識為主。

Slide 17

Slide 17 text

浮現商業結構 - 房貸商業流程分類結果 接待 鑑價 徵信 授信 帳務

Slide 18

Slide 18 text

Domain Storytelling • Domain Storytelling 用於幫助(開發)團隊學習 領域知識,近期開始受到 DDD 愛好者的推崇。 • Domain Storytelling 提倡將不同背景的人們拉在 一起,藉由敘述和視覺化領域故事彼此學習,設計 出符合能充分反映業務架構的系統。

Slide 19

Slide 19 text

利用 Domain Storytelling 尋找邊界 • 可以應用於「劃分領域邊界」,用於 將一個大領域拆分成更小的單元時。 • 劃分原則:從領域專家(業務)的角度, 找到彼此歸屬在一起的活動。 • 舉例:以外送平台為例,可以拆分為 訂餐、備餐、取餐、送餐,四大子領 域。

Slide 20

Slide 20 text

利用 Domain Storytelling 尋找邊界 -以電影院為例 • 顧客向售票員購票的流程為票務子領域。 • 顧客向小販部購買餐飲的流程為餐飲子領域。 • 顧客欣賞電影、播映人員播映電影的流程為播映子領域。 • 顧客入場、與驗票員互動的流程為驗票子領域。 • 整個業務流程可拆分為 票務、餐飲、播映、驗票 四大 子領域。 票務 餐飲 播映 驗票

Slide 21

Slide 21 text

利用 Domain Storytelling 尋找邊界 -以汽車租賃為例 • 顧客與銷售人員互動,選車、簽約的過程歸納為服務提 供子領域。 • 風險人員計算風險和審核契約歸納為風險評估子領域。 • 整個業務流程可拆分為 服務提供、風險評估、汽車管理、 支付 四大子領域。

Slide 22

Slide 22 text

Domain Storytelling 劃分技巧 • 只有一個角色,獨自做了許多事 (Activities that only involve one actor) • 單向資訊流 (One-way information flow) • 不同的觸發點 (Different triggers) • 不屬於這個 domain story 的活動 (Activities supporting something that is not in the picture) • 同樣的事物有不同的名稱 (Difference in language) • 同樣的事物有不同用途 (Different use of the same thing) 劃分原則:從領域專家的角度,找到彼此歸屬在一起(belongs together)的活動。

Slide 23

Slide 23 text

以線上家教 平台為例 業務流程 1. 學生在平台填寫問卷 2. 平台將依問卷內容提供推薦老師清單給學生 3. 學生也可以自行瀏覽所有的老師清單 4. 學生可以點選單一老師,查看該老師的詳細資料 5. 在購課前,學生可以與老師討論學習需求及目標 6. 學生在平台將課程包加入購物車 7. 學生於購物車頁面確認明細後,進行付款 8. 付款成功後,平台提供課程包給學生 9. 在購課後,學生可以與老師討論課程需求 10. 在購課後,學生向老師發起預約課程請求 11. 待老師確認預約請求後,才算預約成功 12. 課程的前10分鐘,平台向ZOOM取得課程連結 13. 平台提供課程連結給學生和老師 14. 學生及老師透過上課連結,進入ZOOM教室上課

Slide 24

Slide 24 text

以線上家教平台為例 依據訪談內容,利用 domain storytelling 方法進行業務流 程建模。

Slide 25

Slide 25 text

以線上家教平台為例

Slide 26

Slide 26 text

以線上家教平台為例

Slide 27

Slide 27 text

小提醒: 業務流程和劃分邊界沒有標準答案, 重點是從業務角度和邏輯思考 找出適合的子領域。

Slide 28

Slide 28 text

從 Sub-domain 到 Bounded Context 我們透過 DDD 戰略設計 來探索並理解業務領域, 但我們的最終目標是要建立軟體,因此需要進一步設計解決方案。

Slide 29

Slide 29 text

從 Sub-domain 到 Bounded Context 以家教平台為例,說到「老師」你會想到什麼?

Slide 30

Slide 30 text

從 Sub-domain 到 Bounded Context 不同團隊/部門的人,對「老師」這個概念關注的地方都不同

Slide 31

Slide 31 text

從 Sub-domain 到 Bounded Context 對應到系統設計,如果沒有明確設計邊界清晰的領域模型,很可能會發生... 我們可以透過 DDD 中 Bounded Context 的概念來設計解決方案。

Slide 32

Slide 32 text

從 Sub-domain 到 Bounded Context 什麼是 Bounded Context? 在系統設計時,定義一組擁有明確邊界、職責清晰的領域模型, 同一個 BC 內使用一致的業務語言、定義、規則,並反映在我們所設計的領域模型中。

Slide 33

Slide 33 text

從 Sub-domain 到 Bounded Context 依據 Sub-domain 來設計以 BC 為基礎的領域模型。

Slide 34

Slide 34 text

從 Sub-domain 到 Bounded Context 我們透過 DDD 戰略設計 來探索並理解業務領域, 但我們的最終目標是要建立軟體,因此需要進一步設計解決方案。 我們可以透過 DDD 分析業務領域,將複雜的領域劃分為數個子領域, 幫助我們來設計以 BC 為基礎解決方案。

Slide 35

Slide 35 text

Domain, Sub-domain 及 Bounded Context • 一個組織所做的事情:要解決什麼問題、問題所處的環境、做事情的方法等等,例如企 業選定一個特定市場,提供產品或服務,如同我們常聽到的 domain know-how。 Domain • 一個 Domain 可能非常的龐大且複雜,我們可以將它拆解為不同的子領域,例如在一個 家教領域中,可以拆分為老師目錄、課程下單、課程預約、課程進行等子領域。 Sub-domain • 在系統設計時,定義一組擁有明確邊界、職責清晰的領域模型,同一個 BC 內使用一致 的業務語言、定義、規則,並反映在我們所設計的領域模型中。 Bounded Context

Slide 36

Slide 36 text

Domain 間 如何溝通?

Slide 37

Slide 37 text

Context Map 定義:Context Maps describe the contact between bounded contexts and teams with a collection of patterns. 理想中,我們希望每個 Bounded Context 獨立自主提供業務服 務(無耦合)。 現實中,多個 Bounded Contexts 互相協作提供業務服務(低 耦合)。 所以接下來我們要識別出 Bounded Contexts 間的關連以及如 何溝通。

Slide 38

Slide 38 text

Context Map - 識別上下游 U: Upstream 上游 D: Downstream 下游 BC BC BC U U D D Downstream 依賴於 Upstream 外部系統 D U

Slide 39

Slide 39 text

上下游間如何溝通的呢? • Bounded Contexts 間的溝通需要中間件。

Slide 40

Slide 40 text

Bounded Contexts 間的溝通需要中間件 使用 DB(不推薦)

Slide 41

Slide 41 text

Bounded Contexts 間的溝通需要中間件 使用 HTTP 同步作法

Slide 42

Slide 42 text

Bounded Contexts 間的溝通需要中間件 使用 Message 非同步作法

Slide 43

Slide 43 text

Bounded Contexts 間的溝通模式 RESTful HTTP Messaging Mechanism

Slide 44

Slide 44 text

REST Client Using an Anticorruption Layer Anticorruption Layer OHS / PL 上游 下游

Slide 45

Slide 45 text

Integration Using Message Context A Context B Event Bus Outbox Outbox Inbox Inbox Event Handler Event Handler Source: GitHub - kgrzybek/modular-monolith-with-ddd: Full Modular Monolith application with Domain-Driven Design approach.

Slide 46

Slide 46 text

Context Map 上加上溝通模式 BC BC BC U U D D 外部系統 D U ACL ACL Queue 同步 非同步

Slide 47

Slide 47 text

Source: Boris | VMware Tanzu Developer Center

Slide 48

Slide 48 text

Source: Boris | VMware Tanzu Developer Center

Slide 49

Slide 49 text

Recap - Domain 間如何溝通?

Slide 50

Slide 50 text

如何設計 Domain?

Slide 51

Slide 51 text

這章節議題很廣。 我想講的是 Bounded Context 中的軟體架構設計。

Slide 52

Slide 52 text

軟體架構設計前言 • 每個 Bounded Context 間各自獨立自主管理,可以依據不同業務場景, 不同 Bounded Contexts 設計不同架構。 三層架構 六角架構 洋蔥架構 簡潔架構

Slide 53

Slide 53 text

軟體架構設計核心 分層 相依

Slide 54

Slide 54 text

分層原則 【高層】 【低層】 Dependencies 低層級的具體 細節組成的。 轉接器、護城河 核心商業邏輯 變 不變

Slide 55

Slide 55 text

依賴規則 Source code dependencies must point only inward, toward higher-level policies. 原始碼依賴關係只能指向內部,朝向更高層級的策略。

Slide 56

Slide 56 text

高層與低層的依賴規則 有一個重要的規則: 低層相依於框架和高層, 高層不相依於任何人。 依賴規則

Slide 57

Slide 57 text

【高層】 【低層】 Dependencies Order Service Data Access Data Providers UI Web Api JSON JSON 依賴規則 – 舉個例子 User 我想查詢 訂單資料 Order Domain

Slide 58

Slide 58 text

【高層】 【低層】 Dependencies Order Service Data Access Data Providers UI Web Api JSON JSON 依賴規則 – 舉個例子 User 我想查詢 訂單資料 Order Domain <> IOrderRepository 透過依賴反轉讓相依永遠從低層指向高層

Slide 59

Slide 59 text

關於高層不相依任何人 I have accepted Log4Net into the core because of its history of stability and small surface area. - Jeffrey Palermo 洋蔥架構提出者 Q:意思是最高層一定沒有相依任何第三方套件嗎? I have accepted Log4Net into the core because of its history of stability and small surface area. - Jeffrey Palermo 洋蔥架構提出者 Q:意思是最高層一定沒有相依任何第三方套件嗎?

Slide 60

Slide 60 text

Recap 軟體架構設計原則 • 遵守分層與相依原則。 • 軟體架構設計是取捨,故打破上述原則也是 OK 的。 • 在原則底下,再思考流量、可用性、效能、可靠性、安全性、強健性、可 擴展性、可維護性、彈性、易用性、可觀測性… 等架構特性。

Slide 61

Slide 61 text

下一步,更細顆粒度的建模 下場講者簡報連結:GOOS&SuppleDesign - Speaker Deck

Slide 62

Slide 62 text

最後想聊聊尖 叫的架構

Slide 63

Slide 63 text

猜猜我是誰? 猜猜我是誰 ├── catalog ├── inventory └── order ├── domain │ └── model │ └── order.ts ├── repository │ └── orderRepository.ts └── useCase ├── createOrder.ts ├── getOrderList.ts └── updateOrder.ts 猜猜我是誰 ├── api ├── application └── domain ├── aggregate │ └── order │ └── order.ts │ └── orderIdVO.ts │ └── catalog │ └── catalog.ts │ └── inventory └── service Source: 軟體架構淺談 - iT 邦幫忙

Slide 64

Slide 64 text

尖叫的架構 • 軟體架構是輔助業務功能開發的工具,要讓架構能凸顯出業務功能本身。 • 若依據業務功能設計軟體架構,有需要隨時可以拆分服務,方便修改。 猜猜我是誰 ├── catalog ├── inventory └── order ├── domain │ └── model │ └── order.ts ├── repository │ └── orderRepository.ts └── useCase Bounded Contexts 架構

Slide 65

Slide 65 text

總結

Slide 66

Slide 66 text

關於領域驅動設計 • 軟體開發的本質是滿足業務領域。 • 越複雜的領域,越需要被設計。 • 越複雜的領域越難設計,所以我們要將複雜的大問題拆分多個小問題。 • 小問題逐一解決,就沒有大問題了。 • 所謂領域驅動設計,核心就在拆分,確立各種邊界(Boundary)。從 Domain 到 Sub-Domains 到 Bounded Contexts 到 Aggregates,一路 從戰略需求面到戰術實作面。 • 然而複雜領域無法一個人處理,所以要團隊大家與領域專家一起面對領域。

Slide 67

Slide 67 text

簡單的領域,或許你不需要領域驅動設計 Source: Implementing Domain-Driven Design

Slide 68

Slide 68 text

若專案分數在七分以上,推薦使用領域驅動設計 Source: Implementing Domain-Driven Design

Slide 69

Slide 69 text

最後 好的軟體架構是適當的精心設計與不斷的演化而來的。

Slide 70

Slide 70 text

Thank you for listening.