DDD - 第三方 API 接口应该在哪里?

DDD - Where should third-party API interfaces should be?

如果我们考虑一个标准的持久存储库,解决方案很简单。我们将 IStuffRepository 放在领域层,将 StuffRepositoryImplementation 放在基础设施层。

但是当我们想要包装第三方时,好的模式是什么API?

我们可以应用相同的模式,在领域层有一个 IStuffGateway,在基础设施层有一个 StuffGatewayImplementation。

但是这种方法有一个问题。当我们考虑持久层时,我们可以控制我们持久化的数据。但是当我们考虑第三方API时,我们没有控制权,这意味着我们可以尝试拥有某个接口签名,但它必须受到我们包装的内容的影响。因此,如果我们更改实现(将第三方替换为另一个),接口签名可能会更改,域也会更改。

另一种方法可能是将接口移到域外,并将其放入基础层及其实现。这样,应用层就可以毫无问题地使用它(并保持域完好无损)。但是这种方法从域中删除了重要的概念,从我的角度来看这似乎很糟糕。

对此有参考文献的意见吗?

我总是保持我的 Domain 对象 (Aggregates) 纯净,没有副作用。这意味着我没有从 Domain 到任何其他层的任何依赖项。 persistence/repository 总是在 Infrastructure 中。 Application 层使用它来持久化 Aggregates.

当我使用CQRS时,我只保持write/command方面(Aggregates)的纯净。 Readmodels 依赖并针对特定实现进行了优化。最近我用了很多MongoDB来坚持。

当我不使用CQRS时,我保持整个Aggregate没有依赖(我别无选择,拆分将是CQRS)。

因此,在所有情况下,Domain 不会执行任何 IO,它没有副作用。这主要是因为在并发更新的情况下,我需要能够在 Aggregate 上安全地重新执行命令。

如果您决定使用接口,您应该使用 DIPDomain 拥有 Interface;这意味着 域决定方法的数量和签名

我同意康斯坦丁的观点。

您可以仍然将概念保留在您的域中,而不是 IO。应用层应该提供所需的域对象。您可以调用您的反腐败层 (IStuffGateway) 并获取所需的对象,然后通过对您的域的一些调用传递这些对象。

如果这是一项常见任务,您可能需要引入一个应用程序服务 (IGetStuffAndCallDomainTask) 来包装该位。