写点什么

DDD-9- 聚合划分

作者:南山
  • 2024-08-27
    江苏
  • 本文字数:1211 字

    阅读完需:约 4 分钟

1、定义

  • 将实体和值对象划分为聚合并围绕聚合定义边界

  • 选择一个实体作为聚合根,并仅允许外部对象持有对聚合根的引用

  • 作为一个整体来定义聚合的属性和不变量,并把执行责任赋予聚合根或者指定的框架机制

2、特性

  • 具有整体与部分的关系

  • 第二,具有不变规则,而且这种不变规则在并发的时候可能被破坏

3、作用

  • 提升了对象系统的粒度

  • 保障业务完整性

  • 减少出错概率

  • 每个聚合都会形成保证事务一致性的边界

    事务边界由商业动机决定,因为任何时候都是业务来决定对象集的有效状态应该是什么

4、划分原则

  • 事务一致性

    只能在一次事务中修改一个聚合实例并提交

  • 生命周期一致性

    是指聚合边界内的对象,和聚合根之间存在“人身依附”关系。

    即:如果聚合根消失,聚合内的其他元素都应该同时消失

  • 问题域一致

    事实上问题域一致是限界上下文(Bounded Context)的约束

    聚合作为一种战术模式,所表示的模型一定会位于同一个限界上下文之内

  • 场景频率一致

    经常被同时操作的对象,它们往往属于同一个聚合。而那些极少被同时关注的对象,一般不应该划为一个聚合

    操作场景不一致的对象,或者说如果一个对象在不同场景下都会被使用,应该考虑把它们分到不同的聚合中

    小聚合

5、经验法则

  • 在聚合边界内保护业务规则不变性

  • 聚合要设计的小巧

  • 整体部分只是聚合的特征之一,还需要考虑小聚合,事务边界一致性(业务级别的)

  • 聚合包含大量实体的情况,拆分成多个小聚合

  • 每个聚合可以更容易地实现,更容易测试

  • 使用最终一致性更新其他聚合

6、关键点

  • 业务规则才是驱动力,最终决定在单次事务完成提交后,哪些对象必须是完整、完全和一致的驱动力

7、设计步骤

  1. 聚合要设计得小巧

  2. 每个聚合一开始创建时只允许包含一个实体,并且它将作为聚合根

  3. 聚合边界内保护业务不变性规则

  4. 在上一步中,已经声明了至少在单个实体持久化时所有内在字段/属性必须是最新的

  5. 但是现在需要一个一个地检查每个聚合。

  6. 在检查聚合 A1 时,问问领域专家需不需要更新其他已定义的聚合,来响应聚合 A1 发生的改变

  7. 为每个聚合和它的一致性规则制作一个清单,还要记录所有这些基于响应的更新的时间范围

  8. 换句话说,“聚合 A1”作为清单的标题,如果其他的聚合类型也需要更新来响应 A1 的变化,就把它们罗列在 A1 之下

  9. 现在询问领域专家,每个基于响应的更新可以等待多长时间

  10. 对每一个即时发生的时间范围(3a),应该坚定地考虑把这两个实体合并到同一个聚合的边界之内。

  11. 对于每一个在给定等待时间(3b)内更新的响应聚合,则遵循最小化聚合原则:“利用最终一致性更新其他聚合”。

8、辅助理解

  • 聚合是对象之间的关系

  • 在聚合内部使用对象导航,跨聚合则使用 ID 导航

  • 为了确保不变规则不被破坏,总的原则是:聚合外部对象对非聚合根对象只能读,不能写,必须通过聚合根才能对非根对象进行访问

  • 因为聚合的不变规则往往不是单个对象能够处理的。比如说,“同一技能不能录入两次”这个规则,通过查看单独的技能对象是无法验证的,必须查看员工的全部技能,才能判断一条新技能是否重复。所以这种规则必须由聚合根或者相应的领域服务负责验证。


用户头像

南山

关注

采菊东篱下,悠然见南山~ 2018-05-04 加入

黄沙百战穿金甲,不破楼兰终不悔!

评论

发布
暂无评论
DDD-9-聚合划分_领域驱动设计_南山_InfoQ写作社区