DDD:汇总根需要来自另一个汇总根的信息

时间:2019-03-16 08:29:28

标签: architecture domain-driven-design aggregateroot

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

目前他有2个聚合根:

  1. User:保存与display namelinked accountsprofile之类的用户有关的信息,该用户可以是patient profile或{{1} }。这样的患者资料包含care provider profilebirth date之类的信息。我有一个gender,负责获取和保存用户。
  2. UserRepository:根据这些长度和权重保存有关健康的信息(例如长度和体重测量值)以及各种计算出的信息(例如“短期演变”)。我有一个Screening负责获取和保存用户。

因此ScreeningRepository中有一个Calculate()方法,目标是将Screening和/或weight添加到length时,系统会立即重新计算screening之类的运行状况属性,以使short term evolution始终处于一致且正确的状态。

问题在于该计算还需要用户screeninggender,这些用户存储在birth date中。

因此,基本上,聚合根patient profile依赖于聚合根screening。所以我想知道如何去做...

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

    < / li>
  2. 如果ScreeningRepository没有对screening的引用,则user没有所有需要的信息。因此,这意味着我可能应该将其移至域服务,该域服务将Calculate()user作为输入并进行计算。精细。但是,如何确定将测量添加到筛选后,screening会被触发?

  3. 我正在考虑的另一种选择是不使Calculate成为聚合根,而使其仅与父级screening聚合。这也使我可以更好地验证user,因为我也可以访问screening。它将解决有关计算的所有问题,因为我手头将拥有所有信息,但是通过这种方式,User将同时负责处理UserRepository,并且我的聚合根将成为{{1 }}和screening

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

2 个答案:

答案 0 :(得分:1)

没有魔术。

如果Screening的域逻辑要求性别和生日,那么您需要将这些值的副本复制到汇总中。反过来,这意味着(a)传入值,或(b)传入支持查询值的功能。

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

答案 1 :(得分:1)

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

  

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

它永远与数据无关,而始终与行为有关。只是一个实践建议:在第一次迭代中,将整个有界上下文变成单个聚合,所有内容都放在单个对象中。

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

似乎,通过使用封装了当前Screening逻辑和SetWeightInKg(w)来修改体重的Screen()方法,患者概况可能是聚集根的良好候选者。护理人员资料可能是另一个汇总。帐户另一个。所有人都只是持有一个UserId供参考。

目标是将属于在一起的不变式放在单个集合中,将不存在的不变式分开,这都是为了提高性能。