【问题标题】:Enforcing a business rule operating on aggregate root collections执行在聚合根集合上运行的业务规则
【发布时间】:2021-04-13 00:42:13
【问题描述】:

我的域中有 2 个 AR:

  1. 产品 - 我想这个名字说明了一切 - 这是合作伙伴销售的东西。它属于:
  2. 合作伙伴 - 卖方。

这是一个多租户系统,其中一个假设是合作伙伴可以拥有数十万种产品,具体取决于限制 - 如果 A 公司只想销售 100 种产品,他们会购买最便宜的青铜通行证,如果他们想卖出 100 000 件产品,他们就购买了 Gold Pass。在产品导入过程中,应强制执行这些规则,因此在任何特定时刻,任何合作伙伴都不能在我们的系统中保留超过限制规则允许的产品。

Product AR 是一个很大的——它包含约 10 个业务规则和约 12 个 ValueObjects。 Partner AR 很小 - 它仅包含 Id 和电流限制值。

从代码角度看导入过程的外观: 我正在从数据库中加载合作伙伴,并为其分配当前活动产品的 id 集合。然后,当产品数据进来时,我首先通过一个方法运行它:Partner.LimitProducts(Products),它返回一个允许放入数据库的产品列表。

我没有将产品作为合作伙伴集合(因此属于它的实体)的严格部分,原因有两个:

  1. 性能 - 我使用的是 NoSql - 文档数据库,它无法很好地保存大型文档。
  2. 常识 - 产品 AR 如此之大绝非偶然,因为所讨论的微服务中发生的 99.999% 的操作仅与产品有关,它甚至从未触及合作伙伴 - 除了创建新产品,即.

但是我发现这种方法存在一些问题。对我来说,DDD 就是在聚合(不变量)中做出强有力的保证,但是当我使用一个 AR 作为对另一个 AR 的一种过滤层时,在这种情况下,它立即迫使我放置协调逻辑在所涉及的两个 AR 之上的一层,这在我看来只是一半的不变量位于错误的位置(这将是应用程序层),但它应该在哪里呢?我考虑过创建一个域服务来将协调逻辑放置在其中,甚至将限制业务规则移到那里,但我不知道我是否喜欢这样......

你们中有人看到这个的替代设计吗?

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    如果合作伙伴聚合只有限制,那建议您:

    • 让合作伙伴聚合负责协调(例如,要求产品创建(和删除,对于您的域中的任何删除方式)通过合作伙伴聚合)
    • 删除合作伙伴聚合,因为它在您的域中没有任何用途

    我可能会让合作伙伴聚合保持(如果您的语言/数据库可以有效地维护这样的集合,最好是一组)跟踪哪些产品(仅需要 ID)与合作伙伴相关联。如果这被证明太大而无法可靠地持续存在,那么我将对产品集进行分片并有效地使每个分片成为自己的聚合(您可以变得非常聪明并自适应地对聚合进行分片)。

    【讨论】:

    • 您的描述说“没有合作伙伴应该能够保留更多产品”也强烈表明产品创建/加载通过合作伙伴聚合。
    • 我考虑过这种方式,不喜欢的原因有一个:产品聚合列表只有在添加新产品的情况下才会通过合作伙伴聚合,这样超过合作伙伴的产品数量限制不会通过。但是,在其他所有情况下(正如我所说,有 10 多个产品操作,并且还会有更多)合作伙伴聚合保持不变,因为这些操作仅在产品上执行。
    • 在这种情况下有效地让合作伙伴管理他们的产品只会导致冗余的合作伙伴聚合方法。
    • 我目前的想法是让合作伙伴只是一个实体——一种配置数据包,因为它主要是这样的——并且总是通过执行该限制规则的域服务推出新产品。似乎是程序性的,感觉有些不对劲,但我认为这是使其两者兼备的唯一方法 - 存储最佳且可读。
    猜你喜欢
    • 2021-12-22
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    相关资源
    最近更新 更多