DDD:大聚合根 - 人

问题描述 投票:0回答:4

我正在构建一个管理人员信息的系统。我有一个不断增长的聚合根,称为“人”。它现在有数百个相关对象、姓名、地址、技能、缺勤等。我担心的是,Person AR 不仅破坏了 SRP,而且随着越来越多的东西(尤其是集合)添加到其中,会产生性能问题。

我不明白如何使用 DDD 将其分解为更小的对象。以缺勤为例。该人员有缺勤记录的集合(开始日期、结束日期、原因)。这些当前通过人员进行管理(BookAbsence、ChangeAbsence、CancelAbsence)。添加缺勤时,我需要验证所有其他缺勤,因此我需要一个可以访问其他缺勤的对象才能进行此验证。

我在这里遗漏了什么吗?是否还有其他我未识别的 AR?在过去,我会通过“AbsenceManager”服务来完成此操作,但我想使用 DDD 来完成此操作。

我对 DDD 还很陌生,所以也许我错过了一些东西。

非常感谢......

domain-driven-design aggregateroot
4个回答
2
投票

这确实是聚合设计如此棘手的原因。所有权并不一定意味着聚合。人们需要了解该领域才能给出正确的答案,因此我们将使用很好的 ol'

Order
示例。
Customer
不会有
Order
对象的集合。最简单的规则是考虑删除 AR。那些在没有 AR 的情况下“可能”有意义的对象可能不属于 AR。不过,一个 Customer 很可能有一组
ActiveOrder
对象。当然,会有一个不变量表明,如果客户有有效订单,则无法删除该客户。

另一件需要注意的事情是臃肿的有界上下文。可以想象,您可能有一个或多个尚未识别的有界上下文,导致 AR 执行过多操作的情况。

因此,就您而言,如果删除

Absence

,您可能仍然对

Customer
感兴趣。对于
OrderLine
,如果没有
Order
,它就没有任何意义。所以没有自己的生命周期。

希望能有那么一点点帮助。


1
投票
Absence

时,AbsenceFactory 可用于验证其他 Absence 代码示例: public class AbsenceFactory { private AbsenceRepository absenceRepository; public Absence newAbsenceOf(Person person) { List<Absence> current = absenceRepository.findAll(person.getIdentifier()); //validate and return } }

你可以在蓝皮书中找到这个模式(如果我没记错的话第6.2节工厂)

在其他“修改”情况下,您可以引入
规范

public class SomeAbsenceSpecification { private AbsenceRepository absenceRepository; public SomeAbsenceSpecification(AbsenceRepository absenceRepository) { this.absenceRepository=absenceRepository; } public boolean isSatisfiedBy(Absence absence) { List<Absence> current = absenceRepository.findAll(absence.getPersonIdentifier()); //validate and return } } 您可以在蓝皮书中找到此模式(第 9.2.3 节规范)


有点晚了,但是,除了@EbenRoux 的注释之外,巨大的聚合根通常意味着上下文映射做得不好。对破碎实体的恐惧以及在有界上下文之间集成数据会导致巨大的聚合根。


0
投票

我认为你的 Person 模型的一部分应该位于一个名为 ProfileContext 的上下文中,它管理一般信息。另一部分应该在AttendanceContext中,依此类推。

我正在构建一个管理人员信息的系统。

-4
投票
您确定通过 SQL 编辑/查询 RDBMS 表的简单 CRUD 应用程序不是一种更便宜的方法吗?

如果你能用数据关系和表操作来表达大部分业务规则,那么你根本不应该使用DDD。

我有一个不断增长的聚合根,称为 Person。

如果您实际上有复杂的业务规则,不断增长的聚合通常是未定义(或错误定义)

上下文边界

的症状。

© www.soinside.com 2019 - 2024. All rights reserved.