领域驱动设计概念解析

领域驱动设计相关名词概念

  • 领域
    要解决的业务问题域(业务范围)
  • 子域
    领域进一步拆分为多个子域,每个子域对应更小的问题域(业务范围)
  • 核心域
    决定产品和公司核心竞争力的子域
  • 通用域
    被多个子域使用的通用功能子域
  • 支撑域
    既不包含决定核心竞争力的功能,也不包含通用功能的子域

实体

•定义

•在DDD中有这样一类对象,它们拥有唯一标识符,且标识符在历经各种状态变更后仍能保持一致。

•对这些对象而言,重要的不是其属性,而是其延续性和标识,对象的延续性和标识会跨越甚至超出软件的生命周期。我们把这样的对象称为实体

•特点

•有 ID 标识,通过 ID 判断相等性,ID 在聚合内唯一即可。 状态可变,它依附于聚合根,其生命周期由聚合根管理。

•实体一般会持久化,但与数据库持久化对象不一定是一对一的关系。

•实体可以引用聚合内的聚合根、实体和值对象

•值对象

•定义

•通过对象属性值来识别的对象,它将多个相关属性组合为一个概念整体。 在 DDD中用来描述领域的特定方面,并且是一个没有标识符的对象,叫作值对象

•特点

•无 ID,不可变,无生命周期,用完即扔。值对象之间通过属性值判断相等性。 它的核心本质是值,是一组概念完整的属性组成的集合,用于描述实体的状态和特征。

•值对象尽量只引用值对象

•聚合

•定义

•领域模型内的实体和值对象就好比个体,而能让实体和值对象协同工作的组织就是聚合, 它用来确保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性

•设计步骤

•1.采用事件风暴,根据业务行为,梳理出在投保过程中发生这些行为的所有的实体和值对象

•2.从众多实体中选出适合作为对象管理者的根实体,也就是聚合根

•3.根据业务单一职责和高内聚原则,找出与聚合根关联的所有紧密依赖的实体和值对象

•4.在聚合内根据聚合根、实体和值对象的依赖关系,画出对象的引用和依赖模型

•5.多个聚合根据业务语义和上下文一起划分到同一个限界上下文内

•设计原则

•1.在一致性边界内建模真正的不变条件。聚合用来封装真正的不变性, 而不是简单地将对象组合在一起。聚合内有一套不变的业务规则,

•各实体和值对象按照统一的业务规则运行,实现对象数据的一致性,

•边界之外的任何东西都与该聚合无关,这就是聚合能实现业务高内聚的原因。

•2. 设计小聚合。如果聚合设计得过大,聚合会因为包含过多的实体, 导致实体之间的管理过于复杂,高频操作时会出现并发冲突或者数据库锁,

•最终导致系统可用性变差。而小聚合设计则可以降低由于业务过大导致聚合重构的可能性,

•让领域模型更能适应业务的变化

•3. 通过唯一标识引用其它聚合。聚合之间是通过关联外部聚合根 ID 的方式引用, 而不是直接对象引用的方式。外部聚合的对象放在聚合边界内管理,

•容易导致聚合的边界不清晰,也会增加聚合之间的耦合度

•4. 在边界之外使用最终一致性。聚合内数据强一致性,而聚合之间数据最终一致性。 在一次事务中,最多只能更改一个聚合的状态。如果一次业务操作涉及多个聚合状态的更改,

•应采用领域事件的方式异步修改相关的聚合,实现聚合之间的解耦

•5. 通过应用层实现跨聚合的服务调用。为实现微服务内聚合之间的解耦, 以及未来以聚合为单位的微服务组合和拆分,应避免跨聚合的领域服务调用和跨聚合的数据库表关联。

•特点

•高内聚、低耦合,它是领域模型中最底层的边界

•聚合根

•定义

•如果把聚合比作组织,那聚合根就是这个组织的负责人。 聚合根也称为根实体,它不仅是实体,还是聚合的管理者。

•如果需要访问其它聚合的实体,就要先访问聚合根,再导航到聚合内部实体,外部对象不能直接访问聚合内实体

•特点

•聚合根是实体,有实体的特点,具有全局唯一标识,有独立的生命周期。 一个聚合只有一个聚合根,聚合根在聚合内对实体和值对象采用直接对象引用的方式进行组织和协调,

•聚合根与聚合根之间通过 ID 关联的方式实现聚合之间的协同