领域模型:聚合、聚合根详解

  聚合和聚合根是领域模型里面很重要的一个概念,其实我们在从真实世界对业务对象进行识别和概念建模的时候,关注的就是聚合根,这才是我们真正要管理的业务对象。一个对象可能有多个层次,也可能有多个子实体,但是这些子实体都不可能孤立存在,它们必须依附于一个聚合根存在,它们和根节点具有同样的生命周期。

  如果一个客户消亡,客户联系方式,客户的多张银行账户信息将不再有任何意义。如果一张采购订单头消失,那么采购订单明细没有任何存在的意义。客户,采购订单,发票这些从真实业务中转化过来的业务对象才是真正的领域核心对象。这些对象可能在领域建模的时候会分解到多个Entity或Value Object,但是一定要意识到实际的聚合在哪里?我们真正关注的业务对象实体究竟有哪些?

  为什么如此强调领域模型,强调聚合根的概念,因此我们在关注领域模型的时候将有助于我们打破原有的关系型数据库的思维模式,转化为对象和领域的思维模式。可以看到领域建模和聚合根的思路正是既适合于关系型数据库,也适合NoSql数据库的建模思路。因为在NoSQL持久化的时候,我们看到采购订单就是一个对象,其它明细和关联信息都是这个对象下的子实体信息,采购订单应该作为一个对象整体进行查询和存储,我们并不关系NoSQL会如何去存储这个对象。让我们正在关注领域对象,而不是去关心如何持久化。

  聚合Aggregate就是一组相关对象的集合,我们把它作为数据修改和访问的单元。每个聚合都会有一个聚合根和聚合的边界Boundary,边界定义了在一个聚合里面内部应该有哪些实体,哪些子实体对象。定义边界的原因是我们期望对一个聚合的访问是通过聚合根点进行的,聚合里面的子实体对外界是完全封闭的。对于外部对象不应该去访问到一个聚合边界里面的子实体。

  在一些场景下,对于一个聚合的访问,我们往往只需要查询到头信息,而不关心具体的子实体信息,这个有点类似于传统O/R Mapping里面的惰性加载。在这里也必须要考虑到。在实现和设计聚合的时候,需要考虑到这种场景,即根据需要来加载一个完整聚合中的实体和子实体,以满足性能的需要。如何对应关系型数据库,对一个聚合实际的新增变更处理则可能涉及到多个数据表的多次操作,而这已经是仓储接口和仓储实现需要考虑的问题。现在对一个聚合的一次操作一定应该在一个完整的事务里面,以保障实际的事务完整性要求。

  按实际对象分析思路,在领域模型中的领域对象分析应该按照从顶向下的思路进行展开,如果这样的话首先识别到的就是聚合根对象,然后再考虑对聚合根对象进行展开,在聚合根对象的展开过程中进一步细化子实体之间的关联和依赖关系。

posted @ 2013-05-25 17:34  PowerZhang  阅读(...)  评论(...编辑  收藏