领域驱动设计
术语
Entity实体
Factory工厂:一种封装机制,把复杂创建逻辑封装,抽象出创建的对象类型;
Function函数:没有副作用的操作;
Repository仓库:一种把存储、检索行为封装起来的机制,类似于对象集合;
Service服务:一种作为接口提供的操作,无封装的状态;
Standalone class(孤立的类);
Value Object值对象:
Ubiquitous Language:通识语言,术语;
分层模式(Layered Architecture)
原则
任何元素仅依赖本层其他元素或下层元素。(内聚)
向上通信需要通过间接传递机制(回调、观察者模式)。
有边界的上下文(Bounded Context)
常用分层结构
- 用户界面层
- 应用层:简单、不包含业务规则
- 领域层:表达业务概念、模型
- 基础设施层
模型元素
Entity(Reference Object)
特征:
- 一种表示事物的对象;
- 具有唯一标识(由标识区分,而不是属性区分)
- 用于识别、查找、匹配对象;
- 生命周期内就有连续性
- 形式、内容可变;
建模思路:
设计标识:
- 必须具有唯一性(即标识一致为同一实体)
- 属性+唯一性约束
- 实例名+唯一符号数字
- 必须具有唯一性(即标识一致为同一实体)
属性:与标识有关的属性留在实体内;(关注必要属性、避免陷入细节属性)
行为:转移到关联的其他对象中;
确保连续性(措施:保持实体简练)
示例:
- 一个人(标识:身份证号、name、手机号、地址等);
- 一个座位(标识:座位号);
- 仿真软件中一个元器件标识;
Value Object
特征:
- 描述一个事务的特征,表示状态属性的对象;
- 包含的属性形成一个整体;
- 标识的分配会导致模型的复杂度增加,VO不分配标识
- 设计为不可变,
- 简化实现(避免在模型中产生不必要的约束)
- 保证安全
- 使用新的替代更改
- 可以引用entity:比如路线是VO,城市是Entity
- 避免双向依赖;
示例:
- address是一个VO,包含:street、city、state
复制和共享
| 优点 | 缺点 | 场景 | |
|---|---|---|---|
| 复制 | 可能导致被大量对象阻塞 | 实现可变 | |
| 共享 | 节省数据空间减少对象数量 | 减慢分布式系统的速度 | 传递引用通信开销低对象不可变 |
Service
特征
- 用于表示动作或操作;(动词)
- 不属于任何entity或者OV;
- 避免导致对象的混乱;
建模思路
- 接口由领域模型定义
- 无状态
- 参数或结果为Entity或者OV
MODULE(PACKAGE)
特征:
- 高内聚、低耦合
按技术分包
按需求任务分包
对象之间的关联
基于同样属性的遍历机制
关联越少越简单
Entity的双向关联难以维护
VO双向关联无意义
对关联进行规则限定,可以简化模型;
关联的控制
- 定义遍历方向
- 定义限定符
- 消除不必要的关联
领域模型和UML的区别
细节层次
- 领域模型 :
- 抽象程度较高,关注的是业务概念和逻辑。
- 不包含实现细节,如方法、数据类型、访问修饰符等。
- 例如,领域模型可能只表示“订单”和“客户”之间的关系,而不涉及订单如何保存到数据库。
- UML 类图 :
- 细节程度更高,可以包含类的属性、方法、访问修饰符、参数类型等。
- 适合用于设计阶段,帮助开发人员理解系统的实现细节。
对象生命周期的管理
AGGREGATE聚合
定义对象的所属关系和边界;
外部对象无法引用聚合内部的entity(除了根entity);
可以传递VO
FACTORY工厂
职责
- 创建复杂对象(AGGREGATE)
特征
- 每个创建方法是原子的
- 工厂应该被抽象为所需的类型
- 合理选择输入参数
- 区分entity factory 和 VO factory
REPOSITORY仓库
查找对象
在模型中加入对象或关系,将概念显示表达出来
柔性设计
Intention Revealing Interfaces
组件的使用者,应该不需要研究其内部实现;
命名中描述效果和目的,不要表露通过何种方式实现;
Side Effect Free Function
命令
查询
Assertion
Conceptual Contour概念轮廓
Standalone Class
Closure of operation闭合操作
保持模型的完整性
明确定义模型应用的上下文;