【问题标题】:Is injecting repository in aggregate root / entity considered bad design?在聚合根/实体中注入存储库是否被认为是糟糕的设计?
【发布时间】:2017-12-17 14:46:41
【问题描述】:

我正在尝试了解领域驱动设计的详细信息,我遇到了这个问题。 我发现了很多例子:

  1. 在域中定义存储库接口
  2. 在其他地方定义存储库实现
  3. 将存储库接口注入聚合根目录

另一方面,也有一些例子严格反对它,并从服务中执行所有与存储库相关的事情。

我找不到权威的答案和解释:这是否被认为是一种不好的做法?如果是,为什么?

【问题讨论】:

  • 为了更好地回答你的问题,我先退后一步,想一想:为什么需要聚合内的存储库?
  • 可能更适合Software Engineering
  • @GoloRoden 例如有Aggregate.Save() 方法,里面会使用IRepository 接口来保存。当然,另一种选择是拥有一个创建聚合实例的服务,调用它需要的任何业务操作方法,然后调用IRepository.Save(Aggregate aggregateInstance)。 (如果这回答了你的问题)
  • 我现在的回答与@VoiceOfUnreason 在他们的回答中已经写的类似。所以我不会添加另一个答案,但我会 +1 :-)
  • 感谢您的评论!如果您有任何要添加到@VoiceOfUnreasons 答案的内容,请将其放在另一个答案中,我会投票赞成。

标签: domain-driven-design


【解决方案1】:

我找不到权威的答案和解释:这是否被认为是一种不好的做法?如果是,为什么?

是的,主要是因为混淆了许多不同的问题。

聚合定义了一致性边界;任何状态更改都应限制在属于同一聚合的相关实体的集合中。因此,一旦您查看了第一个(“根”实体),您应该能够实现更改,而无需检查此域实体图和您已传递的参数以外的任何数据。

换句话说,Repository 是一个管道 问题,而不是 问题。您的域实体负责表达您的域,而不会混入基础架构问题。

例如有一个 Aggregate.Save() 方法,该方法将在内部使用 IRepository 接口进行保存。

Aggregate.Save() 肯定表示有问题。好吧,确切地说,有两个问题:Save 可能不是您的通用语言的一部分,而且很可能Aggregate 也不是。

Save 不是域问题,而是持久性问题 - 它只是将数据从内存表示(易失性存储)复制到持久表示(稳定存储)。您的域模型不需要对此有任何了解。

您发现“有很多例子”的原因之一是正确分离这些问题是困难;这意味着您确实需要深入思考问题才能将它们分开。大多数示例都没有,因为当您总是将所有内容部署在一起时,将事物分开并不重要。

【讨论】:

  • “保存可能不是你常用语言的一部分”——谢谢你的这句话!这是完全有道理的,是的,我绝对忽略了 DDD 的这方面。我专注于保存实现的位置以及它的外部域(和注入)似乎可以接受的事实。但是考虑到域的主要目的,save 绝对不属于泛在语言。这说明了“回归本源”的重要性。非常感谢您的回答!
猜你喜欢
  • 2012-02-28
  • 1970-01-01
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2015-09-22
  • 2021-05-30
  • 1970-01-01
相关资源
最近更新 更多