【问题标题】:In DDD, where to place a "find or create" kind of logic?在 DDD 中,在哪里放置“查找或创建”类型的逻辑?
【发布时间】:2018-03-19 13:15:35
【问题描述】:

要求

在某个用例中,我们得到一个字符串...

StringX = "some value"

我们想要获得一个 [Object A],其属性 [Property X] 与此字符串匹配。 如果没有 [Object A] 与该值匹配,则需要创建它(因此标题 find 或 create)。

创建 [对象 A] 的过程比仅向数据库中添加条目更复杂。

问题

如果这只是找到我可以做的对象的问题:

$objectARepo = new ObjectARepository();
$objectA = $objectARepo->findByStringX($stringX);

但是,可能没有与 StringX 匹配的 ObjectA,需要创建它。

我正在努力决定如何处理这个逻辑。

服务应该这样做吗?但是服务不应该用于搜索对象,不是吗?

这样的事情有意义吗?

$objectAService = new ObjectAService(new ObjectARepository());
$objectA = $objectAService->findOrCreateByStringX($stringX);

【问题讨论】:

  • 你想要一些方法,比如 firstOrCreate 或 firstOrNew?
  • 您能详细说明您的用例吗?在找不到聚合根时默默地创建聚合根是非常不寻常的。
  • @MahdiYouseftabar 我想知道这种方法的合适位置。
  • @guillaume31 添加了详细信息。我不想默默地创建对象,因此想明确地将其称为“findOrCreate”,而不仅仅是“find”并将其放置在存储库中。如果不存在,我认为存储库不应该决定做某事
  • 通常,findOrCreate 方法用于技术层以避免重复,但不会暴露给最终用户。是这种情况吗(您的其他详细信息没有说明“我们”是用户还是程序员)?

标签: php laravel domain-driven-design


【解决方案1】:

如果未找到业务逻辑需要创建一个新的聚合,这种情况并不常见,因为创建时您通常需要聚合的所有属性。而对于搜索来说,它只是其中的几个。

现在让我们假设这需要完成。我建议它不应该是一个名为 findOrCreate() 的存储库函数,因为存储库应该只关心持久性而不关心对象的创建方式。最好的位置是调用存储库的服务(通常是应用程序服务)。

$objectA = $this->objectARepo->findByStringX($stringX);
$objectA = $objectA ?? $this->createNewObjectA($stringX);
$this->objectARepo->add($objectA);

createNewObjectA() 将包含与为新创建的对象设置默认值相关的逻辑。如果您的聚合很复杂,您可以使用工厂。

【讨论】:

    猜你喜欢
    • 2011-08-02
    • 2011-09-08
    • 2019-07-02
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多