聚合设计-《复杂软件设计之道:领域驱动设计全面解析与实战》笔记 – 3

文章目录

  • 1. Top Level
  • 2. 聚合设计的概念
    • 2.1. 高聚合低关联
    • 2.2. 聚合的逻辑一致性
      • 2.2.1. 业务数据(结构)
      • 2.2.2. 业务行为
      • 2.2.3. 结论与目标
  • 3. 设计聚合的几种方法
    • 3.1. 改变主谓宾顺序
    • 3.2. 根据领域事件
    • 3.3. 根据单一职责设计聚合
    • 3.4. 按时间边界设计聚合
    • 3.5. 通过事务边界设计聚合
    • 3.6. 通过ER模型设计聚合
  • 4. 总结

1. Top Level

聚合设计是DDD战术设计中的一部分。通过有界上下文划分团队,使用统一语言命名上下文;聚合设计则是进入有界上下文内部讨论其结构

如果说有界上下文解决了领域内的划分,那么聚合就解决了有界上下文内对象之间的划分。所谓划分就是将紧密的放一起,让松散的更加松散,甚至没有关系。从这里能看出DDD的一种收缩趋势,各领域分别向以聚合为核心的方向设计

2.1. 高聚合低关联

业务逻辑体现在各种数据、行为的关系上,因此,聚合设计也重在关系处理,对关系的敏感性成了设计聚合的要点。

聚合本身就是一种高聚合,聚合内部的对象都是在数据和行为上高度关联和一致的,除此以外的其他关系就被抛弃了。这里鲜明地主张了一种非黑即白的可行动的设计理念——如果关系不是很紧密,那么就隔断,如果非常紧密就放在一起。

在类的关联上,有一种关系叫聚合(Aggregation),聚合关系是一种更强的紧密关联,代表一个类是另一个类的一部分。有两个特性:

  • 传递性:如果A是B的一部分,B是C的部分,那么A就是C的一部分。
  • 反对称性:如果A是B的一部分,那么B不会是A的一部分。

除了聚合还有组合(Composition)。组合是一种较强的聚合关系,这两种关系基本相同,不同之处在于,在组合关系中,部件对象任何时候只能从属于一个整体对象,两者的生命周期是一样的。

DDD中的聚合设计就是要找出这两种更强的关联。它们都是比普通关联更加严格紧密的关系,普通关联关系就可以舍弃,这正是高聚合低关联的设计原则

2.2. 聚合的逻辑一致性

**业务逻辑的一致性需要从两个方面去保证:业务数据和业务行为。**这两个方面缺一不可,正如传统系统中,如果只设计数据表结构,而没有SQL调用,就不能实现业务逻辑,同样,如果只有SQL调用,而没有事先设计的表结构,业务逻辑同样无法得到实现。

实现逻辑一致性是聚合存在的根本目的。高聚合低关联只是体现逻辑一致性的一个方面,更多的逻辑一致性不但体现在结构关系上(业务数据结构),还体现在行为动作的执行上(业务行为)。

2.2.1. 业务数据(结构)

高聚合低关联,可以看成是从结构关系上确立业务对象的紧聚合关系,割裂除了聚合以外的关系,这样业务对象就能形成一个有主从之分的结构,而不是如同蜘蛛 那样混乱的关系结构

2.2.2. 业务行为

业务逻辑的一致性还体现在行为的逻辑关系上:

  • 行为发生是有顺序的
  • 行为发生是一致的(比如即使部分数据变化了,其他数据也应该跟着变化整体达成一致)

这些行为的逻辑关系往往是业务规则,而聚合是保证业务规则实现的地方。一般相同业务规则会在同一个有界上下文中实现,具体来说就是在聚合中实现

2.2.3. 结论与目标

聚合的逻辑一致性是最终在聚合根这个类中实现的,那么类的行为就成为逻辑一致性最终落地的保证。如何通过类的行为保证逻辑一致性从职责角度去设计:

  • 决定(deciding):为了做一个决定,一个对象也许需要知道一些信息。
  • 知道(knowing):为了知道某些信息,一个对象也许需要做一些事情。
  • 做(doing):为了做某个事情,一个对象也许需要知道一些信息。

为了规范从职责行为思考领域的习惯,可以引入按合约设计(DesignbyContract,DBC)模式,它分三个部分。

  1. 预先条件:职责行为发生条件。包括:何时/何地/为什么/如何触发、策略、约束和委托行为,这个可以使用“命令”表达。
  2. 后置条件:在一个对象被认为处于一个新状态时,应该通过什么标志来判断,返回结果或断言,这个可以使用“领域事件”表达。
  3. 不变性:描述了一些专有特征不应该在行为事件发生后变化(主要是业务规则或逻辑一致性等),无论这个类有多少实例,也无论它什么时候被其他对象访问。

这里重点强调的是 命令 + 事件 + 不变性

通过领域事件发现有界上下文(比如上文中的事件风暴会议),更进一步,有界上下文发现了,下一步就是有界上下文内的聚合。命令是具体落到聚合根这个对象上,当聚合根根据业务规则或逻辑执行了这个命令,实际上就代表聚合根内部的状态发生了改变,一些事实发生了,聚合根再抛出领域事件。

传统数据库设计是先有数据表才有关系表,而DDD的革命性正是在这里——先有关系才有关系内的对象,这也是维根斯坦逻辑哲学中“对象只有在关系中才有意义”的一个体现。

3.3. 根据单一职责设计聚合

聚合的逻辑一致性不但表现在紧凑的结构关系上,还表现在高度一致、高度凝聚的职责行为上,这也是OOAD中单一职责的一个实现。

从职责角度,聚合模型有以下特征:

  • 信息拥有者模型。当一个对象是信息的拥有者时,它的职责是“知道这些信息”,不应该期望和其他对象协作获得这些已经知道的信息

这么E-R模型中往往会发现下面的聚合关系:

%E8%81%9A%E5%90%88%E8%AE%BE%E8%AE%A1%20f594e/Untitled%206.png

4. 总结

通过引入标识将事物分为主次两个方面,这是DDD建模中主要的思维方法之一:首先将问题空间划分为核心领域和辅助领域,将领域划分为不同的子域,然后集中精力攻克核心领域。在解决方案里,通过逻辑一致性划分有界上下文,找到有界上下文的标识——聚合,再找到聚合的标识——聚合根,当然聚合根也有标识,比如可以是一个ID字段

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年2月15日
下一篇 2022年2月15日

相关推荐