【问题标题】:DDD: aggregate root needs information from another aggregate rootDDD:聚合根需要来自另一个聚合根的信息
【发布时间】:2019-08-07 06:12:22
【问题描述】:

我正在考虑一个相当简单的问题的设计,但我想听听其他解决方案来正确处理它。

目前我有 2 个聚合根:

  1. User:保存有关用户的信息,例如display namelinked accountsprofile,可以是patient profilecare provider profile。此类患者资料包含birth dategender 等信息。我有一个 UserRepository 负责获取和保存用户。
  2. Screening:保存有关健康的信息,例如长度和体重测量值,以及基于这些长度和重量的所有类型的计算信息,例如“短期进化”。我有一个 ScreeningRepository 负责获取和保存用户.

所以Screening中有一个Calculate()方法,目标是当weight和/或length添加到screening后,像short term evolution这样的健康属性会立即重新计算, 使screening 始终处于一致且正确的状态。

问题是这个计算还需要用户的genderbirth date,存储在patient profile中。

所以基本上,聚合根screening 依赖于聚合根user。所以我想知道该怎么做......

  1. 根据 DDD,聚合根不应引用另一个聚合根。而且,如果我将user 设为screening 的属性,ScreeningRepository 也将负责将用户非实体化,这当然不是他的任务。

  2. 如果screening 没有引用user,则Calculate() 没有所有需要的信息。所以这意味着我可能应该将它移动到一个域服务,它以userscreening 作为输入,并进行计算。美好的。但是,如何确保将测量添加到筛选中时会触发Calculate

  3. 我正在考虑的另一个选项是不将 screening 设为聚合根,而将其设为与父 user 的聚合。这也让我可以更好地验证screening,因为我也可以访问User。它将解决有关计算的所有问题,因为我手头有所有信息,但是这样,UserRepository 也将负责处理screening,而我的聚合根将负责usersscreenings .

在这一点上,最后一个选项似乎是唯一可以轻松解决问题的选项,但我很想听听任何想法,因为我可能会遗漏明显的概念。

【问题讨论】:

    标签: architecture domain-driven-design aggregateroot


    【解决方案1】:

    聚合是 DDD 中最容易被误解的概念。

    用户:保存有关用户的信息,例如显示名称

    这与数据无关,它始终与行为有关。只是一个实践建议:在第一次迭代中,让你的整个有界上下文成为一个聚合,一切都在一个对象中。

    会发生什么?首先,您现在能够满足有界上下文中可能存在的每个不变量。好的,但是你会说这太疯狂了,我不能将所有内容都加载到单个对象中,这将非常慢,并且在此期间没有其他人可以使用该对象。正确的!聚合只有一个原因:性能优化!由您自己决定找到从不相互影响的不变量,以便您可以拆分对象以提高系统的性能。如何拆分对象?

    似乎患者资料可能是聚合根的一个很好的候选者,其方法 Screen() 封装了当前的筛选逻辑和 SetWeightInKg(w) 以修改权重。护理提供者资料可能是另一个汇总。帐户另一个。所有人都只是持有一个 UserId 以供参考。

    我们的目标是将属于一起的不变量放在一个聚合中,并将不属于的不变量分开,这一切都是为了性能。

    【讨论】:

    • 您的建议与 Vaughn Vernon 在他的“领域驱动设计蒸馏”一书中给出的建议相反。在 Tactical Design With Aggregates 一章中,他谈到了如何调整聚合的大小,第一步是“设计小型聚合”,第二条规则虽然更重要,但在流程中紧随其后,是“保护业务聚合边界内的不变量”。
    【解决方案2】:

    没有魔法。

    如果Screening 的域逻辑需要性别和出生日期,那么您需要将这些值的副本放入聚合中。这反过来意味着(a)您传递值,或者(b)您传递支持查询值的功能。

    通常情况下,聚合会缓存“属于”另一个聚合的数据的本地副本。在这种情况下,如果需要使缓存的数据失效,您可能需要处理会发生什么(例如:如果我们后来发现生日数据输入错误会发生什么?)

    【讨论】:

    • 感谢您的意见!我遇到的另一个问题是,如果筛选无法引用用户,我无法完全验证筛选,例如,您可能会为没有患者资料的用户创建筛选。现在,我只是重新组织了所有内容,以便筛选现在成为用户 root 的一部分,只是为了试一试。这解决了我遇到的所有问题,但 UserRepository 现在还检索/保存筛选和测量。我计划添加一个布尔值 IncludeScreening,以便您可以指定是否应加载筛选。我认为这让我两全其美......
    • 如何以这种方式传播更改?复杂性和各种问题将呈指数级增长。
    猜你喜欢
    • 2015-01-04
    • 2016-11-29
    • 1970-01-01
    • 2016-03-21
    • 2016-03-29
    • 1970-01-01
    • 2013-07-10
    • 2018-08-12
    • 1970-01-01
    相关资源
    最近更新 更多