領域驅動設計與簡潔架構入門實作上課筆記
murmur
Teddy 的這堂課真的很不便宜…但有這個價值. 上完後, 感覺會飛喔 XD
有閒錢的話, 可以去上一下.
領域驅動設計與簡潔架構入門實作班
Domain Driven Design 定義
何謂 Domain ?
- 應用程式邏輯所圍繞的知識和活動範圍 –– 特定知識或專業為基礎的範圍
- 翻譯成白話文就是 在真實世界中, 你的軟體所要解決的問題範圍
- 例如 : 電子商務、醫療系統、保險系統、銀行系統、叫車系統、定位系統 等等
- Domain 有大有小
ps : 通常 DDD 在講的 Domain 是指 Problem Domain , 但 Problem 會省略, 所以會只講 Domain
參考資源
聊聊名詞 | 問題領域與解決方案領域 | Problem & Solution Domain
- Domain: 特定知識或專業為基礎的範圍。
- Context: 指特定事物的背景與先決條件。
- Problem Domain: 以特定知識或專案為前提條件,需要處理或解決的問題。一個問題可能會有多組的解決方案。
- Porblem Space: 所有可能的問題集合。
- Solution Domain: 以問題所屬的領域為主,針對性的解決方案。一個解決方案,也可能應用到多個問題域。
- Solution Space: 所有可能解決方案的集合。
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
何謂 Domain Model ?
Most developers have never seen a domain model. They've only seen data models.
Domain Modeling means forming an opinion on how it behaves
Domain Model 並不是指程式碼. 而是對於對於問題領域(Problem Domain)的概念化抽象. 目的在於將現實世界中的商業邏輯、實體、行為和關系抽象為模型, 以便開發人員和領域專家能夠清晰地溝通.
Domain Model 雖然是問題領域的抽象化, 但會由 Solution Domain 的人負責建立以及維護(RD)
ps : 問題領域的人負責出嘴(提供必要的領域知識) QAQ
Domaind Model 並非越真實越好. 僅需要真實到可以解決問題.
因此了解你的需求/問題很重要!!!
舉例 : 我們不會要求 "捷運地圖" 要有完美的比例尺啥的. 因為這不能解決問題
圖示
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
參考資源
What is a Domain Model?
EVENTSTORMING
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Modeling your Domain with Event Storming workshop
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
何謂 Driven ?
- 要有 X 才能驅動 –- 代表某事物是被 X 驅動
- 例如
BOSS-Driven-Design(BDD)
Deadline-Driven-Design(DDD)
- Test-Driven-Design(TDD) –- 被測試所驅動(沒有測試, 不能設計)
- Behavior-Driven-Design(BDD) –- 被驗收測試所驅動(沒有驗收測試, 不能設計)
- Use-Case-Driven-Design
- Use-Story-Driven-Design
- Domain-Driven Design – 被領域模型所驅動
何謂 Design ?
建築師 Alexander 說 : 設計就是決定 Form 與 Context 的邊界 –- 設計就是決定你的產品要長甚麼樣子
建築師 Alexander 說 : 設計應該是由上而下的.
Form : 你的最終產品/解決方案/實作
Context : 描敘問題發生的上下文 – 想成是情境或是假設前提可能比較好理解
Forces 是決定邊界的因素
如何套用設計模式?
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
可以簡單把 Forces 想成是 作用力 or 約束條件 or 限制好的設計師會看到比較多的 Forces !
- Forces 越多, Form 越清晰
- Forces 有優先權 – 有強有弱 (跟力的大小的概念很像)
- 無法分析 Forces, 就無法決定 Form 的形狀
- 如果沒有 Forces, 那你的 Form 長甚麼樣都可以吧 XD
ps : Domain Expert 的意見是一種 Forces, 但非絕對. 仍需要考量其他的 Forcs( e.g. Dead line or 老闆 … ), Form 的邊界會在所有 Forces 作用後決定.
所以何謂 Domain Driven Design ?
Domain Driven Design 就是透過領域模型去驅動你的設計 !
- 開發軟體時專注於 Domain 中的重要概念與 Business logic, 並透過與領域專家緊密溝通, 共同建立領域模型(domain model), 再以此模型作為軟體實作的基礎.
- 基本與傳統物件導向分析與設計(OOAD)作法類似, 但實作細節不同. 可視為 OOAD 的進階版本, 但更適合於現在分散式與反應式(事件驅動)的系統開發 – Teddy 個人看法XD
- DDD 適合的原因
- Bounded Context
- Aggregate
- Domain Event
Paul Rayner's 3 Pillars of DDD
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
你的 Form 會跟這三個元素有關
- Context
- Problem
- Solution
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Ubiquitous Lanagage is a common language shared in a particular bounded context
為什麼需要 Bounded Context ?
- It is difficult ot have an Ubiquitous Lanagage in one big context
- e.g. 假設世界是一個context , 這世界有超過100個國家…就有超過100種語言…
- Single big context results in one complex object model
因此, 將一個大的 context 拆分成數個小的 Bounded Contexts 是必要的
開發流程示意圖
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Domain Expert 是了解問題的人(可能也知道答案)
傳統上 OOAD 的作法 與 DDD 的比較
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
OOAD
- OOAD 假設軟體開發可以完美地各司其職(分工). – 每一個階段會產出一個 Model
- OOAD 假設各個階段進行模型轉換的時候不會有資訊遺失
- OOAD 假設當需求變更時, 每一個階段的人都會確實地修改他們的領域模型
OOAD |
Analysis |
Design |
Coding |
腳色 |
SA |
SD |
RD |
行為 |
跟領域專家釐清需求, 然後出規格書 |
依據規格書, 產出 UML (類別以及類別間互動) |
依據UML, 程式碼實作 |
模型 |
Domain Model(SA) |
Design Model(SD) |
Implementation Model(RD) |
DDD
DDD 不要 模型轉換 , 希望大家都用相同的 Domain Model 溝通
DDD |
Analysis |
Design |
Coding |
腳色 |
知道商業邏輯的任何人 |
知道商業邏輯的任何人 |
RD |
行為 |
Strategic Design |
Tactical Design |
程式碼實作 |
模型 |
Domain Model |
Domain Model(同左) |
Domain Model(同左) |
參考資源
領域驅動設計學習筆記(1):學習的切入角度(上)
Strategic Design
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
The high level design of the problem domain (分析問題的工具包)
Strategic design is the subset of DDD that operates at a higher level. Its main goal is to help dealing with large models, and its challenge is to achieve modularity without compromising the benefits of integrating different business operations. Because in large systems such design decisions must be negotiated between teams, strategic design does not take into account only technical considerations, but it often becomes the intersection between design and politics.
DDD Strategic Design patterns belong to the Problem Space. In this space, we focus on performing high-level analysis of the domain and its constraints, staying away from technical details. It's not about writing a code or thinking of any specific tech stack, or architecture.
Defining explicit context boundaries is not only one of the essential aspects of DDD, but also, along with core domain distillation and large-scale structures, one of the keystones of strategic design. While it is theoretically possible to have a single, consistent model for the whole enterprise, this approach is rather complex and generally impractical. Therefore, letting each team develop its own models and explicitly limiting their applicability is the viable way to go. This pattern is commonly known as bounded context.
there are several steps we could try
- Identifying and defining the business Core Domains and Subdomains.
- Establishing clear boundaries between different parts of the system (Bounded Contexts).
- Developing a shared language (Ubiquitous Language) within each Bounded Context.
- Mapping relationships between different Bounded Contexts and Teams (Context Mapping).
- Aligning the software architecture with the business strategy and domain structure.
名詞說明
- Core (Sub) Domain : 核心業務
- Supporting (Sub) Domain : 對核心業務的輔助 – 仍與業務邏輯有關(有最好, 沒有也行)
- Generic (Sub) Domain : 跨多個業務的通用功能 (可使用現成套件)
參考資源
Domain-Driven Design (DDD): Strategic Design Explained


DDD Model Integrity Patterns
Ubiquitous Language
A shared language that is used by all stakeholders in a project to improve communication and reduce misunderstandings.
The Ubiquitous Language is
- owned and maintained by the Team,
- developed in a collaborative loop
- expressed in the software model
- context dependent
- not “given” — it’s carefully developed by a Team
Bounded Context
Bounded Context is
- linguistic and semantic boundary for the Ubiquitous Language
- conceptual boundary around a specific model of Core Domain
Bounded contexts alleviate languages conflict between contexts
A bad split of contexts, mixing up elements of distinct models, may cause two kinds of problems:
- Duplication of concepts :
- When there are two model elements (and corresponding implementations) that represent the same concept.
- False cognates:
- When two people use the same term (or implemented object) thinking they are talking about the same thing, but they are not.

An ubiquitous language is a common language shared in a particular bounded context
How to define bounded contexts ?
- Business boundaries/organization structures
- Activities that, from an actor's perspectives, belong together
- One-way information flow
- Different meaning for the same noun
- Different triggers (time vs. on demand) bounded contexts.
我忘了這裡在講啥, Alex 救命QAQ
參考資訊
Bounded Context
How Domain Storytelling reveils the secrets of your domain - Henning Schwentner, Stefan Hofer
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Context Maps
Context Maps represent the relationship among bounded contexts
A Domain-specific Language (DSL) as a formal approach for DDD
The Context Mapper DSL provides a tool to create context maps according to the meta-model introduced above in a formal manner.
The following illustration shows the context map of the insurance scenario inspired by the representation of Vernon and Brandolini. The complete example and short descriptions of the bounded contexts can be found here.

- 第一組
- Partnership: two teams integrate their software systems closely, treating them as one combined system and sharing the model code across team boundaries. This mapping style is suitable when the teams have a trustful relationship and a substantial overlap in their domain models.
- Customer-Supplier: one team (the supplier) develops a software system that is consumed by another team (the customer), with a clear upstream-downstream relationship between the two teams.
- 第二組
- Shared Kernel: involves multiple teams sharing a subset of the domain model, which is treated as a shared kernel, while each team maintains its own context and model for the rest of their respective domains.
- 共同核心的改變, 需要經過所有使用核心的團隊的同意
- Separate Ways: teams work on completely separate systems with no integration or shared model, essentially ignoring the existence of other systems and teams.
- 第三組
- Conformist: one team (the conformist) adheres to a model defined by another team, essentially treating the other team’s model as the central, canonical model.
- Anticorruption Layer: involves creating a translation layer between two different models, allowing them to communicate without tightly coupling or requiring changes to their respective models.
- 上游團隊的設計會先經過防腐層(Anticorruption Layer)的轉換(下游團隊可以接受的格式) 才進入下游團隊.
- 第四組
- Open Host Service: one team (the host) provides a service that can be extended by other teams through plugins or adapters, enabling a centralized system with extensibility points.
- 標記是否是給全世界使用. (不會明確知道下游是誰, 想使用的人自己來透過上游團隊定義的合約)
- 微軟的 Library , 你不能亂改合約(合約可以是任何形式 e.g. interface or API), 會死人的!
- Published Language: involves one team (the publisher) defining and publishing a language or protocol that other teams use to integrate with the publisher’s system, without sharing the internal model.
- 通常跟 OHS 搭配使用. 可以是 Json / XML /GRPC 等等, 重點是 Published Language <–> Domain Models 的轉換過程中不能遺失資訊 or 被汙染
參考資源
Context Mapper: A DSL for Service Decomposition
Shared Understanding


參考資源
Shared Understanding
User Story Mapping

User Story Mapping (使用者故事對照)
Event Storming
介紹
Event Storming is a fun collaborative modeling technique invented by Alberto Brandolini that enables members from different teams and disciplines to participate in workshops to learn how to break down complex business domains and processes.
There are multiple levels that Event Storming workshops can be run at. Each level continues to refine and enrich the domains with new concepts until a full end-to-end flow of the system is visualized. This end-to-end flow is valuable to the business itself but also helps accelerate software design and development.

- Big Picture (aka 30,000 foot view)
- 依據時間發生先後,在一面「巨大」的牆上,貼上Domain Event、External System、People,並藉此流程觀察Hot Spot(對商業流程有模糊不清、商機、痛點等)。
- Explore the whole business across multiple boundaries by gathering people who each own/understands one part of the truth
- All Domain events are described in past tense (past tense because it's an event that happened, its a fact that cannot be changed)
- Capture HotSpots or points of contention in a domain (this is usually when the experts don't all agree on a concept)
- Map the relationships between the domain and external dependencies
- Example Event :
- InvoiceCreated
- InvoiceReceived
- EmailSent
- ReportUpdated
- Key Words
- Read Model : 輔助做決定的資訊
- Policy : 依據"條件" 決定後續的動作
- Process Modeling (aka 10,000 foot view)
- 基於前一個階段的產出,加上Read Model、Policy、Command
- Model a single business process from beginning to end and ensure no ambiguity or contention exists by clarifying all the business rules
- Enforce a timeline so that you can move events into the right order, and eventually see a process or flow emerging.
- Attach the actors, their motivations, and any dependencies required for executing actions (aka Commands)
- Enable stakeholders, domain experts and developers to communicate via ubiquitous language (all participants are able to communicate using the same terminology)
- Software Design
- 加上Aggregate
- Now we have an end-to-end model of the system
- All relevant concepts are captured and documented
- The software design phase can proceed using methods from Domain-Driven Design (DDD), Clean Architecture and CQRS. Each sticky note can potentially turn into a Product Backlog Item during the software development phase.
參考資源
Do you know the value of Event Storming?
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Event Storming — The Storm That Cleans Up The Mess!
Collaborative Process Modelling with EventStorming
How EventStorming facilitated knowledge transfer and discovery in a complex business domain
EventStorming
Event storming—Kick-start your microservices architecture
Model Event Storming Results in Context Mapper
Remote Event Storming Takeaways
Design Level Event Storming with examples!
領域驅動設計學習筆記(13):幫Event Storming加上使用者介面
Teddy 的教材例子
我印象很模糊了 = =
需要 Alex 支援
BC ezKanban
- 團隊一起想有哪些 Event 會在 ezKanban 發生
- 按照發生時間順序排序
- 若發現有相同的東西(字不一樣), 團隊討論要留哪一張
- 過程中大概會像是這種感覺
- 概念類似的東西放在附近, 整理一下, 並補上對應的 Command/ Read Model / Policy. 做完大概會像是下圖
- 補上 Aggregate
- 線連起來
用 Specification by Example 驗證自己的 domain Model




- 一路精煉


- 功能可使用 Event Souring 完成
小組練習的成果, 紀錄一下 XD

Tactical Design
The detailed design(aka, DDD building blocks) –- 設計的工具包

Domain Event
- 領域專家/利益關係人感興趣的事件
- 兩種 Domain Event 類型
- Bounded Contexts 內傳遞

- Event Bus 的實作要求低
- 傳遞至 Bounded Context 之外
- 可避免跨 BC 之間的相依
- Board BC 可以直接從 DB 取出 Account BC 的資訊
- 可能需要 kafka 等等專業的 Event Bus 工具0
- 有狀態改變的才是 Domain Event
- Domain Event 不是 UI Event
- 用途
- 狀態同步 –- eventual consistency
- Event Sourcing
利用 Domain Event 同步不同 Aggregate 的狀態

Software Architecture
定義
- The architecture of a software is the shape given to that system by those who build ii
- The form of that shape is in the division of the system into components, the arrangement of those components, and the ways in thich those components communicate with each other
軟體架構形狀的目的是什麼 ?
- The purpose of the shape is to facilitate the development, deployment, operation, and maintenance of the software system contained within it
- The strategy behind that facilitation is to leave as many options open as possible, for as long as possible.
- Defer commitment in lean software development
架構越靈活就能越晚做決定 – 有充足的時間做 survey
軟體架構基本上與功能無關
- The architecture of a system has very little bearing on whether that system works. There are many system out there, with terrible architecture, that work just fine.
- Their trouble do not lie in their operation;rather, they occur in their deployment, maintenance, and ongoing development.
雖然架構與功能無關, 但好的架構要能夠讓使用者看得出系統的功能
The ultimate goal of software architecture is to minimize the lifetime cost of the system and to maximize programmer productivity
軟體架構師需要寫程式嗎?
- Software architect is a programmer; and continues to be a programmer
- Software architects may not write as much code other programmers do, but they contunue to engage in programming tasks.
- They can not do their jobs properly if they are not experiencing the problems that they are creating for the rest of the programmers.
A good architect maximizes the number of decisions not made
Design and Architecture
- The low-level and the high-level structure are all part of the same whole. No clear dividing line separates them. There is simply a continuum of decisions from the gihgest to the lowest levels
如何評量設計品質
- 衡量滿足客戶需求的工作量
- 如果工作量很低, 而且在整個軟體生命週期都保持很低, 那該設計就是好的設計
Clean Architecture
As Known as :
- Hexagonal Architecture、Ports and Adapters、Onion Architecture
特性 :
- Independent of framework
- TestAble
- Independent of the UI
- Independent of the database
- Independent of any extenal agency
The Ultimate Detaiil – Main Component
- It is in this Main component that dependencies should be injected by a Dependency Injection framework
- Once they are injected in Main, Main should distribute those dependencies normally, without using the framework.
- Think of Main as the dirtiest of all the dirty components
其他實作細節 :
- DDD
- Aggregate 狀態與 Domain event 發送的一致性
- 透過 Aggregate Root 存取內部物件時, 應該傳送 Immutable entities
- Clean Architecture
- Package by: Layer, Feature, Component?
整潔架構三原則
分層原則 Layered Architecture
- Layered architectures are said to be the most common and widely used architectural framework in software development. It is also known as an n-tier architecture and describes an architectural pattern composed of several separate horizontal layers that function together as a single unit of software. A layer is a logical separation of components or code
- Now, the number of layers in a layered architecture is not set to a specific number and is usually dependent on the developer or software architect.

It is important to note that this framework will usually always have a user interaction layer, a layer for processing, and a layer that deals with data processing. These are described further as:
- Presentation Layer : responsible for user interactions with the software system
- Application/Business Layer : handles aspects related to accomplishing functional requirements
- Domain Layer : responsible for algorithms, and programming components
- Infrastructure/Persistence/Database Layer : responsible for handling data, databases

- 誰是高層(重要!)? 誰是低層? 這是個重要的問題.
- 原則上離 I/O 越遠的 Layer 有越高的層級

Clean Architecture 的四個預設階層
- Entities
- 傳統 OOAD 所說的 Domain Model Object, 存放核心商業邏輯
- What the system is
- User Cases
- 應用程式邏輯, 扮演著 Controller 的腳色, 負責呼叫 Entities 或是 類似於 IRespository 這樣的提供應用程式對外的服務.
- What the system does.
- Interface Adapters
- 將外部資料與呼叫介面透過此層轉呼叫 User Case, 如此一來 User Case 就可以與 I/O 或是應用框架無關
- Frameworks and Drivers
- 包含應用程式框架, 資料庫或常見的 MVC 框架. 通常該層的程式只是為了把應用程式框架與內部的 Interface Adapters 或 User Cases 串起來的膠水程式, 鮮少有複雜的商業邏輯位於這一層.
ps : 最重要的是 Entites 和 User Cases 這兩層, 如果系統不複雜, 另外兩層其實可以考慮合成一層就好.
相依性原則 Dependency Rule
分層之後如何管理各層之間的相依姓?
A: 低層相依於高層
Source Code Dependencies must point only inward, toward higher-level policies.(程式碼相依性必須只能往內,指向更高層級的策略)
透過依賴反轉達成相依性原則

滿足相依性原則可以獲得兩大好處,首先,因為高層的物件不再相依於框架等低層的物件,所以測試碼可以單獨測試,大幅簡化測試的工作。
其次,系統的核心功能位於Entities與Use Cases這兩層(蛋黃區與蛋白區),要更換I/O或是應用程式框架「理論上」變得簡單很多。例如,如果要將Web-Based UI換成Android App,只需異動最外面兩層(Framework & Drivers與Interface Adapters),便可直接銜接原本的Use Cases與Entities。
CA 的檔案結構配置參考
- Project-Name
- XXX-Bounded-Context (folder)
- Adapters (folder) <– 由內往外第三層
- Usecases (folder) <– 由內往外第二層
- In (folder)
- Out (folder) –- 會跟 Adapters 對照 (實作放在 Adapters內)
- XXX-User-Case.cs
- Entitiies (folder) <– 最內層

跨層原則

將軟體架構分層並且確認相依性嚴格遵守由外往內(由低層往高層)的這兩個原則之後,接下來會面臨到另一個問題:「物件跨層時該怎麼辦?」。
- Q: 內層物件可否跨層往外傳?
- A: 視情況而定, 若嚴格遵守, 則不行.
- Q: 外層如何將資料傳給內層?
- A: 使用在 User Case Layer 定義好的 InputData

ps : Teddy 順便糾正 CA 那本書在 Data Access 那邊的畫法.
Tedddy 認為現在應該這樣畫會比較好, 上面的畫法是很舊的東西, 可拋棄. e.g. Prestenter

嚴格遵守跨層原則的好處
參考資源
Clean Architecture(6):架構三原則三部曲—跨層原則
「安靜是種超能力」- 從迪米特法則看 Clean Architecture 的跨層原則
Bridge DDD and Clean Architecture

- 從 CA 的角度, DDD 只是幫助分析 Enties Layer 的工具
- 從 DDD 的角度, CA 是 DDD 該做的事情的其中一項
CQRS : Command Query Responsibility Segregation

Query 可以不套用 DDD
Domain Model 就像是一個 State Machine
參考資源
Simple CQRS implementation with raw SQL and DDD

Domains, Commands, and State Machines Oh My!

Summary

參考資源
Simple, Tactical Domain Driven Design in Clojure
Architect Software with Domain Driven Design
Thank you!
You can find me on
若有謬誤 , 煩請告知 , 新手發帖請多包涵
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →