对领域概念做静态建模的时候,有一类概念被视为聚合根(root)。它有自己的生灭过程,数据和行为聚合于其上,有一个唯一的ID可以表征自己并且可以索引到自己的数据。聚合根表征的是一个实体,但并非所有的实体都应该抽象成聚合根(有些可能应该抽象为注入的数据或者一条待处理的消息)。聚合根可以多种类型,且之间可以构成层级关系(或其它关系,如网状或别的什么情况,层级关系自然最简单)。
从业务角度看,它表示领域核心的参与者。比如一个经济模型参与的实体包括,国家,地区(省/州),公司,自然人。这个模型中 国家是一级聚合根(R0), 地区/公司(R1),个人(R2)。
每个聚合根上可以有自己的数据(data)和行为(behavior)。比如国家的数据可以有土地矿藏人口GDP法律,个人的数据可以有年龄技能收入房产等等。国家的行为可以有改变利率出台政策禁止某种产业,个人行为可以有就业辞职买房结婚等等。林林总总的数据和行为必须是为某个特定领域服务的,总是先抽象出聚合根再将各种领域知识/术语聚合于其上。如果大部分概念可以找到一个合适的聚合根,且聚合根之间关系又是尽量简单的,这个描述就可能还不错。比如上述国家经济模型描述,聚合根之间关系比较复杂,因此未必是一个好的抽象。关键是也没有明确这个系统或领域存在的目的(比如分析央行利率是否需要变动,或者获取投资建议)。目的不同,建模抽取的聚合根必然不同。建立好的模型的根本是对系统的充分理解。
虽说认识是一步步深入的,但系统设计要在聚合根抽取这个层面反复的话,比如做了三个月聚合根模型变了,这可能还是灾难性的。因此可以先抽取显而易见的,其它晦涩不定的,需要延迟决策。
有了聚合根,我们应当避免创造上帝类(或超长函数)。而是将聚合根上的数据和行为分类组织,在不同的场景,聚合根参与不同的过程,表现出不同的行为,承担不同的角色。
聚合根上只有data和behavior,这种拆分(或者组织)往往不能找到单一职责的边界,behavior和data仍然可能实现的非常复杂。这种复杂度有可能来源于聚合根所描述实体本身状态(status)的复杂。这个时候,status作为一类特殊的数据,应该被升格成需要单独描述的聚合物。并且behavior和data的拆分需要依赖不同status,简单的说,root参与的过程有若干不同的抽象行为(abstract behavior)组合而成,每个abstract behavior依赖status可以选择不同的实现(implements)。业务处理过程,行为选择过程,行为的具体实现,这三者应该被单独描述(同时它们的变化周期也不相同),这样系统的复杂度才可能被有效降解。至于没用状态的过程,比如数字信号处理,它是严格被算法和公式约束的,其实现难度往往不来自于概念抽取和复杂关系上。