- 根据提供的
信息
完善主要业务场景
和业务流程
; - 根据业务流程识别
领域事件
并按照时序排列
; - 针对领域事件进行
命令识别
; - 针对领域事件和命令进行
聚合
和子域
的初步识别; - 在识别的subdomain中识别
实体
、值对象
、实体间关系
、调整聚合关系
; - 针对领域模型识别
限界上下文
(Bounded Context)。
sequenceDiagram
信息->>业务场景&业务流程: 完善
业务场景&业务流程->>领域事件&命令识别: 识别
领域事件&命令识别->>聚合&子域:识别
聚合&子域->>实体&值对象:识别
实体&值对象->>限界上下:识别
- Focus on your core domain.
Core domain:存在差异性竞争力的业务
- Iteratively explore models.
方法:通过实践和软件(UML)
- speak ubiquitous language.
方法:一种能合作的语言,业务术语(概念)
sequenceDiagram
沟通语言->>代码语言: 通用语言
代码语言->>沟通语言: 通用语言
- 业务事件
- 时间序列
- 所有的事件
- 命名:聚合#动词的过去时
- 命令
- 来源:
1. UI 用户操作
2. 外部系统触发
3. 定时任务
- 注意:
1. cmd:event-->1:1,推荐
2. cmd:event-->1:n,可以,尽量避免
3. cmd:event-->n:1,不可以
- 命名:
动词
- 聚合
- 定义:生命周期相同的领域对象(实体、值对象)的集合。
- 方法:可在cmd和event之间夹出聚合。
1. 每个聚合都有一个根和一个边界。
2. 每个聚合选择其中一个实体作为聚合根,本质是一个实体。
3. 一个actor是一个聚合。
4. 外部通过聚合根访问聚合内领域对象。
5. 尽量小。
- 实体&值对象
- 来源:领域对象,来源于业务概念。
- 值对象:无id,状态不可变
DDD中的值对象与C#的struct很像相似,是不是值对象应该使用struct?
答:struct 作为一种技术选择,有时候也许可行,但或许更多时候是不可行,比如:struct不能为空,使得不能与领域对象对应。
- 实体:有id,有状态
- 限界上下文
- 识别:同一个对象,有时表达的含义不同时,此时可能需要两个限界上下文。
- 尽量大
- 跨限界上下文访问:RPC、REST、MQ
- 尽量使子域和限界上下文对应。
- 技术对应
- 子域、限界上下文对应项目(微服务的话,对应应用服务)
- 聚合对应actor(或者对象类)
- 推荐尽量一个实体对应一个聚合对应一个actor
- 应用服务对应Controller API
- 领域事件对应事件
- 实体反映在数据库表结构
- Repository类似DAO
RESTful架构下“资源”(resource)识别至关重要。在整个DDD建模中,聚合
和实体
都是我们抽象资源的重要入手点。
这种方法比较适合识别Domain层的API设计。
API 最终都要满足业务的需求,所以也有API设计方法从流程节点
的分析出发。
这种设计方法更适合Application层的API设计