DDD - 如何在不与存储库对话的情况下获取另一个聚合根?

问题描述 投票:0回答:1

在这个问题中https://softwareengineering.stackexchange.com/questions/396151/which-layer-do-ddd-repositories-belong-to?newreg=f257b90b65e94f9ead5df5096267ef9a,我知道我们应该避免与存储库交谈。

但是现在我们有一个聚合根,我们需要获取另一个聚合根来检查我们拥有的聚合根是否正确。

例如:

每种资源都有其方案。因此资源将保留其方案的名称。

如果资源想要更新新的资源数据,它需要获取方案实体并要求方案检查新资源数据是否与方案验证器匹配。

要获取方案实体,我们需要询问方案存储库。但他们告诉我我们应该避免与存储库交谈。如果确实需要避免,如何通过名称获取方案实体?

domain-driven-design
1个回答
3
投票

您应该牢记的两个想法:

  • 这些是模式;这些模式在任何地方的表达方式并不完全相同,而是适应我们使用它们的每个上下文。
  • 我们选择让我们的生活更轻松的设计——如果图案妨碍我们,我们就不会使用它。

要获取方案实体,我们需要询问方案存储库。但他们告诉我我们应该避免与存储库交谈。如果确实需要避免,如何通过名称获取方案实体?

基本思想:可以通过遍历找到实体(您从某个聚合根开始,然后不断询问事物,直到到达您想要的位置),root实体可以通过存储库到达。

在《蓝皮书》中,埃文斯假设你可以从一个聚合根到达另一个聚合根;人们往往不会这样做(当您不再假设所有聚合都将存储在同一个数据库中时,您突然需要小心哪些聚合可以同时更改,这反过来又暗示了对您的设计)。

当今,我们会注意到,如果我们不打算更改方案,那么我们根本不需要它的聚合根 - 我们只需要一个验证器,我们可以根据信息的副本创建它。

因此我们将方案信息视为参考数据(参见Helland,2005)。

太棒了 - 那么我们如何获取资源聚合的“参考数据”?

通常采用两种方式之一 - 迄今为止最简单的是将其作为参数传递。应用程序代码(通常与我们将资源聚合从其存储库中拉出的位置相同)还负责查找资源数据。

resource = resourceRepository.get(id)
validator = validatorRepository.get(resource.scheme)
resource.update(validator, ....)

或者,我们可以将查找验证器的功能传递给资源。天真地,这可能看起来像:

resource = resourceRepository.get(id)
resource.update(validatorRepository::get, ....)

但这违反了我们关于在何处使用存储库的“规则”。那么现在怎么办?两个可能的答案:我们决定该规则在这里不适用,或者我们使用类似的模式来获取我们需要的:“域服务”)

resource = resourceRepository.get(id)
resource.update(domainService, ....)

域服务是一种可以用于各种事物的模式;在这里,我们使用它作为一种方便的机制来访问我们需要的参考数据。

从表面上看,它看起来像一个存储库 - 这里的显着区别是该域服务没有能力更改方案实体;它只能读取它们。信息是相同的,但是该信息作为对象的表达是不同的(因为这个对象只有读取方法)。


这是“公正”的设计;机器并不关心我们如何告诉它做什么工作。我们只是试图安排代码,以便它清楚地向下一个出现的程序员传达意图。

© www.soinside.com 2019 - 2024. All rights reserved.