领域驱动设计(Thoughtworks洞见)
上QQ阅读APP看书,第一时间看更新

聚合的封装

DDD元模型中一个核心概念叫“聚合”(Aggregate)。这个从建筑学来的名词非常形象,建筑学上我们翻译为“骨料”,是形成混凝土的重要元素,也是为什么混凝土如此坚固的基础。

(混凝土里的一种骨料)

同理,在DDD建模中,聚合也是我们构建领域模型的基础,并且每个聚合都是内聚性很高的组合。聚合本身完成了我们对骨干业务规则的封装,减小了我们实现过程中出错的可能。

以上面那个订单跟踪领域为例,假设我们允许一个订单下存在多个子订单,而每个子订单也是可以独立配送的,这种情况下我们抽象出“子订单”这个实体。显然订单和子订单存在业务逻辑上的一致性,没有订单的时候不应该创建子订单,更新子订单的时候应该同时“通知”所属的订单。这个时候如果采用把订单和子订单聚合起来的封装就很有必要了。采用聚合抽象的结果就是访问每个子订单都需要从相关的订单入口(i.e.,订单为聚合根),存取时我们都是以这个聚合为基本单位,即包含了订单和订单下面的所有子订单。显然这样的好处是在订单跟踪这个领域模型里,订单作为一个聚合存在,我们只需要一次性梳理清楚订单和子订单的逻辑关系,就不需要在未来每次引用时都考虑这里面的业务规则了。

(订单跟踪领域的订单聚合)

在建模过程中,很多团队并没有努力思考聚合的存在。封装这个在技术实现领域的基本原则在建模时却很少被重视起来。开篇提到在战术建模过程中强调业务领域人员的参与也是为了解决这个问题,聚合的识别实际是针对业务规则的封装,当我们不理解业务规则的时候是无法做出是否封装的判断的。

一言以蔽之,识别聚合是认知潜在核心业务规则的过程,而定义出来的聚合是在大家共识基础上对核心业务规则的封装。