【问题标题】:Bypass an aggregate root to edit individual models绕过聚合根以编辑单个模型
【发布时间】:2011-05-23 23:10:36
【问题描述】:

这是对另一个问题的跟进:Bypassing Aggregate Root

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

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

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

等等

由于产品不是以批次的形式创建的,因此我们在单独的屏幕中逐个编辑聚合根中的每个实体。 由于我们处于无状态系统中,因此我们需要在 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;
    }
}

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

【问题讨论】:

    标签: orm domain-driven-design repository repository-pattern aggregateroot


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 谢谢,我明白了。您是否建议任何其他方法来定位精确项目,同时仍从聚合根目录浏览?
    • 不,您无能为力。您可以编写一些辅助方法,以便隐藏遍历对象、枚举列表等的实际过程,并且调用者似乎执行某种简单的 get 方法,但在 t6e 一天结束时,您仍在从根遍历聚合。
    【解决方案2】:

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

    【讨论】:

    • 这是有道理的。在仍然编辑聚合树深处的单个实体的同时执行这些规则的任何其他想法?
    • 这不可能是使用域驱动设计的另一种方法。尽管您可以使用数据库查询来强制执行此不变量,但这意味着您已将业务逻辑移到域之外。这种方法违反了领域驱动设计并导致了数据驱动的应用程序
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多