gpt4 book ai didi

domain-driven-design - DDD - 域服务实现 : Domain or Infrastructure

转载 作者:行者123 更新时间:2023-12-04 08:52:50 30 4
gpt4 key购买 nike

我有这个经典的 DDD 问题;我有一个做一些事情的域服务“DetectPriority”。
PM 要求我创建 2 个不同的服务;一个 INTERNAL(包含完整的业务规则并涉及许多其他领域模型)和另一个 ETERNAL(一个简单的 API 调用)。
域内有一个接口(interface)“DetectPriorityInterface”。
两个实现必须同时处于事件状态;一种“混合”必须实时选择一个而不是另一个。
问题是:这些实现(两个实现)应该放在哪里:在域层或基础设施层?
内部实现充满了业务规则,应该驻留在领域层。
外部实现是一个简单的调用,应该存在于基础设施中。
我们应该把两者都放在基础设施层吗?
谢谢
编辑
实际上,我们有一个接口(interface)“DetectPriority”和三个实现,都在我们的域层中(临时“错误”解决方案):

  • InternalDetector(带有业务规则)
  • ExternalDetector(使用外部 API 调用)
  • MixerDetector(获取两个实现并处理选择)

  • 客户端使用接口(interface),所以对于应用层,所有这些东西都是透明的;接下来,我们将移除 Internal(或 External)和 Mixer 并仅使用一个实现。 (所有这些背后的想法是了解谁表现更好,这是一个 A/BN 测试)
    我们的内部争论是:因为 InternalDetector 有一些仅属于该检测器的域规则,它应该存在于基础设施层,因为它不是通用域规则。我们中的一些人不同意这一点,因为在 InternalDetector 中我们只有业务规则,而在 Infra Layer 中看不到。
    可能正确的方法应该是在域中添加内部,在基础设施中添加外部..但它似乎有点困惑..
    将所有内容放在 Infra 层中对于开发人员来说更具可读性......
    我们没有在书中找到一些东西,因为通常你只有一个域服务的实现......

    最佳答案

    简短的回答是,您应该在域层实现内部服务,在基础设施层实现外部服务,正如您在问题中所说的那样。这样,一切都会在它的位置。
    另一个需要考虑的重要事情是决定调用哪个服务的代码也应该在域层中。正如我从您的问题中可以想象的那样,您可以使用某些业务规则来决定使用哪个检测器。一个检测器在您的应用程序中实现,而另一个检测器未实现这一事实只是您系统的实现细节。实际上,您只是根据某些条件决定使用一组业务规则或另一组业务规则。这是一个商业决策。
    DDD 通常是关于艰难的妥协。但是当你正在寻找一个好的折衷方案时,我会建议 从不将域逻辑移到域层之外,从不将领域层的引用添加到其他层。
    这是必不可少的。
    这是一个示例,说明如何在不违反这些规则的情况下解决此任务:

    // Names in this code should be changed to something with business 
    // meaning. For example `externalDetector` can be `governmentDetector`
    // and `internalDetector` can be `corporateDetector`.

    // Declare a service interface in the domain layer
    public interface DetectPriority {}


    // Inject both detectors in the domain service.
    // Your dependency injection code should inject here
    // an internal implementation and an external one,
    // implemented in the infrastructure layer.
    // So your DI code knows about different implementations
    // but the domain service doesn't.
    // For the domain service it's just two implementations
    // of domain interface IDetector
    IDetector _externalDetector;
    IDetector _internalDetector;


    // Implement the method of the domain service like this:
    public Priority Detect()
    {
    if (weShouldUseExternalSetOfRules)
    {
    return _externalDetector.Detect(); // this one is implemented in your infrastructure layer
    }
    else
    {
    return _internalDetector.Detect(); // this one is implemented in your domain
    }
    }
    在此解决方案中,您可以看到:
  • 所有域逻辑(内部检测器的实现和决定使用哪组规则)都放置在域层中。
  • 我们没有从我们的域中引用基础设施层。域服务仅引用 IDetector接口(interface),但是这个接口(interface)是在领域层声明的。
  • 领域层没有基础设施代码。在这种情况下,基础设施代码的含义类似于“使用查询字符串中的这组参数调用该 REST 服务的 GET 方法”。显然,这段代码将在 externalDetector执行。

  • 为了确定这是一个好方法,你可以看看 this repository使用著名的 Eric Evans 书中的示例 DDD 应用程序。你可以在那里找到 service interface在域层和 service itself 中声明在基础设施层实现。不幸的是,在这个应用程序的领域层内没有使用这个服务接口(interface)的例子。但它是在域层内部声明的,以使这种用法成为可能。
    您可以在 this great article 中找到相同的方法和很好的解释。 .

    编辑
    根据问题中的新信息,如果是关于 A/B 测试,那么选择检测器是应用程序级别的决定。所有其他事情保持不变。所以:
  • MixerDetector应该在应用层
  • DetectPriority接口(interface)-在域层
  • InternalDetector在域层
  • ExternalDetector在基础设施层

  • 然后,您的探测器就不需要“商业”名称,因为它们实际上是 InternalDetectorExternalDetector .

    关于domain-driven-design - DDD - 域服务实现 : Domain or Infrastructure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64010238/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com