Skip to content

DDD 基础概念

DDD 的基础概念可以分成两组:一组用于划边界,一组用于写模型。划边界时关注领域、子域、限界上下文和上下文映射;写模型时关注实体、值对象、聚合、领域服务、仓储和领域事件。更完整的业务主线说明见 DDD 模型详细说明

概念关系

概念主要回答的问题工程判断
领域系统解决哪一类业务问题不从技术组件命名,而从业务能力命名
子域哪些业务能力重要性不同核心域重点投入,通用域优先复用成熟方案
限界上下文一个模型在哪个范围内成立同词不同义时要拆上下文,而不是做全局大对象
实体哪个对象需要长期追踪身份业务会追问“是哪一个”时,应建成实体
值对象哪组值共同描述一个概念业务只比较值是否相等时,优先建成值对象
聚合哪些规则必须同时保持一致围绕不变量划边界,不围绕数据库外键划边界
聚合根谁控制聚合内部修改外部只通过聚合根修改内部对象
领域服务哪些规则不属于单个对象承载领域行为,不做通用事务脚本
仓储聚合如何保存和取回领域层定义接口,基础设施层实现存储细节
领域事件哪些业务事实已经发生用过去式命名,只表达事实,不表达命令

容易混淆的地方

实体不是数据库表的对象映射。订单实体不只是 orders 表的一行,它应能保护订单状态流转、金额计算、订单项修改等业务规则。值对象也不是附属字段的集合,金额、地址、时间范围这些概念如果有自己的校验和比较规则,就值得独立建模。

聚合不是对象越多越完整。订单、库存、支付都有关系,但不代表它们应该放在同一个聚合里。聚合边界应围绕强一致规则:如果某条规则必须在一个事务中成立,就考虑放进同一聚合;如果可以通过事件、补偿或流程编排完成,就不要把边界扩大。

领域服务不是所有业务逻辑的收纳箱。单个实体或值对象能表达的规则,优先放回对象内部;只有跨对象、跨聚合且仍然属于领域规则的行为,才适合放进领域服务。否则系统会从贫血实体变成“胖服务”。

领域事件不是消息队列的技术别名。它先是业务事实,再考虑是否发布到消息中间件。事件命名和字段应站在业务视角,例如 OrderPaidSendStockMessage 更稳定,因为前者描述事实,后者描述技术动作。

别急,先让缓存热一下。