【问题标题】:DDD: Large Aggregate Root - PersonDDD:大聚合根 - 人
【发布时间】:2013-11-19 20:49:53
【问题描述】:

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

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

我在这里遗漏了什么吗?是否还有其他我没有发现的 AR?过去我会通过“AbsenceManager”服务来完成这项工作,但我想使用 DDD 来完成。

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

非常感谢....

【问题讨论】:

  • 也许 Absence 是另一个 AR。在缺勤时,您需要通过Person强制执行哪些不变量?

标签: domain-driven-design aggregateroot


【解决方案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 节规范)中找到此模式

【讨论】:

    【解决方案2】:

    这确实是聚合设计如此棘手的原因。所有权并不一定意味着聚合。需要了解域才能给出正确的答案,因此我们将使用好的 ol'Order 示例。 Customer 不会有 Order 对象的集合。最简单的规则是考虑删除 AR。在没有 AR 的情况下可能有意义的那些对象可能不属于 AR。不过,Customer 很可能拥有ActiveOrder 对象的集合。当然会有一个不变量表明如果客户有活动订单则不能被删除。

    要注意的另一件事是臃肿的有界上下文。可以想象,您可能拥有一个或多个尚未识别的有界上下文,从而导致您的 AR 做得太多。

    因此,在您的情况下,如果 Customer 被删除,您很可能仍然对 Absence 感兴趣。对于OrderLine,如果没有Order,它就没有任何意义。所以没有自己的生命周期。

    希望对您有所帮助。

    【讨论】:

    • 我参加聚会有点晚了,但是阅读您的回答我有一个问题:如果删除了CustomerOrder 有什么意义?现在,让我们抛开明显的业务规则,即您永远不允许删除至少有一个OrderCustomer。关键是,没有CustomerOrder 几乎毫无意义(没有人付钱,没有人把它送到,等等......)就像OrderItem 没有Order。还是我错过了什么?
    【解决方案3】:

    我正在建立一个系统来管理个人信息。

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

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

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

    如果您确实有复杂的业务规则,那么不断增长的聚合通常是未定义(或错误定义)context boundaries 的象征。

    【讨论】:

      猜你喜欢
      • 2016-06-28
      • 2016-03-21
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多