2

这是对另一个问题的跟进:绕过聚合根

这个问题的作者询问在他的示例中是否可以接受绕过聚合根。我有同样的问题,但针对不同的用例。

我们的 Web 应用程序有一个后台,我们可以在其中编辑属于聚合根的所有项目:

  • 产品(聚合根
  • 选项
  • 选项项目

等等

因为一个产品不是在一个批次中创建的,它的所有选项,我们在一个单独的屏幕中一个一个地编辑聚合根中的每个实体。由于我们处于无状态系统中,因此我们需要在 URL 参数中唯一标识我们想要处理的实体。这意味着,例如,我们将根据其获取和编辑选项id,而不是从根目录浏览。

恕我直言,为每个人都有一个存储库更有意义,只需执行以下操作:

$optionRepository->find($optionId);

而不是类似的东西:

foreach ($product->options as $option) {
    if ($option->id == $optionId) {
        // ok, we finally found it, we can now work on it
        // ...
        break;
    }
}

这是否打破了领域驱动设计中聚合根的概念?在这种情况下,我将非常感谢学习正确的方法。

4

2 回答 2

2

它打破了聚合根的概念。没有“正确”的方法可以做到这一点。要么您决定忽略聚合根规则并直接访问对象,要么您决定遵循聚合规则并从根遍历到对象。您可以以一种或另一种方式做到这一点,实际上没有其他任何可能,因此没有任何第三种选择代表一种“正确”的方式来直接访问对象并仍然遵守聚合根规则。

这是一个选择问题。如果有某种令人信服的理由,我个人会打破聚合根规则。除非列表很大,否则您的建议可能最方便。真的有那么方便吗?您必须创建和维护另一个存储库等。

问题是,一旦您创建了选项存储库,人们就会使用它。随时随地。然后是下一个场景,你肯定还有其他类似的情况。让我们创建另一个存储库。我们在那里做了,为什么不在这里呢?很快,您还不如为每个对象建立一个存储库,无论如何,这最终会发生。

不是说这是好事还是坏事。在没有正式聚合根之前,我曾在应用程序上工作过。我要说的是,这并不是真正的中间立场。如果您要使用它们,那么您必须对聚合根规则持严格态度您要么识别聚合根并始终遵守规则(除非在极端特殊的情况下,您所描述的情况并非如此) ,或者您可能根本没有它们。

一致性可能同样重要。我要么观察总根,要么完全消除它们可以代表的潜在负担。

于 2011-05-24T00:16:05.040 回答
1

如果您不从聚合根加载实体,您将无法强制执行聚合不变量(例如 Product 不能有多个 A 类型的选项)。结果,您的数据可能不一致。

于 2011-05-24T06:04:21.373 回答