gpt4 book ai didi

domain-driven-design - 应用层和基础设施层之间的依赖关系有些困惑

转载 作者:行者123 更新时间:2023-12-04 02:25:19 28 4
gpt4 key购买 nike

  • 当应用程序使用 Repository(它是一个 Infrastructure 服务)时,Repository 接口(interface)在 Domain 层中定义,而它的实现在 Infrastructure 层中定义,因为这样域模型没有传出依赖项。

  • a) 如果我们 100% 确定特定(非存储库)基础设施服务 信息服务 永远不会被域层内的任何代码调用,然后我假设 InfServ的接口(interface)不需要在域层中定义?
  • 假设 信息服务 不会被域层内的代码调用(因此我们不需要在域层内定义它的接口(interface)):

  • a) 如果 信息服务 将被应用程序层的服务调用,我假设应用程序层应该对基础设施层有隐式依赖,而不是相反?换句话说,两者都是 InfServ的接口(interface)及其实现应该在基础设施层中定义吗?
    b) 应用层依赖于基础设施层而不是另一种方式更好的原因是基础设施层可以被许多应用程序重用,而应用程序层在大多数情况下只特定于单个应用程序并且通常不能被其他应用程序重用?
    c) 如果我们 100% 确定域层中的任何代码都不会使用存储库,那么我们就不需要在域层中定义其接口(interface)?
    更新:
    1)

    Yes, however, the definition of domain layer can include applicationservices which act as a facade over the domain. The applicationservice usually references a repository and other infrastructuralservices. It orchestrates domain objects and said services to implementuse cases.


    一种)

    ... which act as a facade over the domain


    我们不能争辩说“常规”(我在我的问题中所指的那些)应用程序服务也充当域的外观吗?
    b)

    The application service usually references a repository and otherinfrastructural services.


    从您的回复看来,您似乎是在暗示(尽管您可能不是)“常规”应用程序服务通常不引用基础设施服务,而实际上它们确实引用了(据我所知)?!
    2)
    一种)

    I usually merge application services, as described above, into thedomain layer.


    “常规”应用层也是 BLL 层的一部分,所以我们不能说它与域层合并(它实际上位于域层的顶部)吗?!
    b)

    I tend to adhere to the Hexagonal architecture style ...


    六边形架构似乎没有明确的应用层(即应用服务)概念?
    C)

    Part of the benefit of declaring a repository interface in the domainlayer is that it specifies the data access requirements of the domain.


    那么即使我们的域代码不会使用它,我们也应该在域层中包含 Repository 接口(interface)吗?
    第二次更新:
    2a)

    If what you call a "regular" application service interacts with thedomain, I think it is acceptable to make it part of the domain"layer". However, the domain should not directly depend on thesurrounding application service and so it is possible to split them upinto separate modules if desired.


  • 我不确定您是否暗示应用层的设计(在传统的分层架构中)与使用例如洋葱架构将应用层与域层合并时的设计有什么不同?
  • 我会说至少就模块而言,两者不应该不同,因为在这两种情况下我们都可以分离应用层和领域层模块? (尽管我必须承认我跳过了伴侣模块(Evan 的书),因为我认为我在学习 DDD 的早期不需要这些知识:O)

  • 2b)

    Yes because it can be contrasted with a layered architecture. A strictlayered architecture does not gel with the idea of declaringrepository interfaces in domain layer and implementing ininfrastructure layer. This is because, on the one hand, you have adependency in one direction, but in terms of deployment the dependencyis in the other. Hexagonal addresses these concerns by placing thedomain at the center. Take a look at the onion architecture - it isessentially hexagonal but may be easier to grasp.


    我还不知道 MVC 模式或 Asp.Net MVC,但无论如何,从阅读本系列的前三部分(让我困惑到我停止阅读它的地步),它似乎:
    a) 来自 Onion article :

    Each layer is coupled to the layers below it, and each layer is oftencoupled to various infrastructure concerns.


    作者暗示在传统的分层架构 TLA 中,域层与基础设施层耦合,这当然不是真的,因为我们通常在域层内定义基础设施接口(interface)(例如存储库接口(interface))?!
    b) 如果在使用 TLA 时我们决定在应用层定义基础架构接口(interface),那么应用层也不与基础架构层耦合?!
    c) 洋葱架构不是一个 * 基础设施层 * 耦合到应用程序核心(包括应用程序层),因为基础设施接口(interface)是在应用程序核心中定义的?
    d) 如果是 c) ,将应用程序层耦合到基础设施层不是更好吗(出于我在原始问题中给出的原因(这里我假设域层不会调用基础设施服务))?
    4)
    来自 Onion article :

    The first layer around the Domain Model is typically where we wouldfind interfaces that provide object saving and retrieving behavior,called repository interfaces.


    来自 Onion article :

    The controller only depends on interfaces, which are defined in theapplication core. Remember that all dependencies are toward thecenter.


    看来作者是在暗示,由于依赖关系只是向内的,而且由于基础设施接口(interface)是围绕领域模型定义的,领域模型中的代码不应该引用这些接口(interface)。换句话说,我们不应该将 Repository 引用作为参数传递给域实体的方法(正如您自己所说的那样是允许的):
    class Foo
    {
    ...
    public int DoSomething(IRepository repo)
    {
    ...
    var info = repo.Get...;
    ...
    }
    }
    由于上述原因,我必须承认我没有看到使用 Onion 架构的好处,甚至没有看到它与 TLA 的区别(假设所有基础设施接口(interface)都在域层中定义)--> 换句话说,我们不能描述 TLA使用洋葱架构图?!
    最终更新:
    2)
    b)

    Yes. In TLA the domain layer would communicate directly withinfrastructure in terms of classes declared by infrastructure layernot the other way around.


    可以肯定的是 - 您是说使用 TLA 将在基础设施层中定义基础设施接口(interface)(我知道使用 Hexagonal/Onion 架构时,它们是在应用程序核心中定义的)?
    d)

    The coupling goes both ways. The application core depends onimplementations in infrastructure and infrastructure depend oninterfaces declared in application core.


    我的观点是,由于使用 Onion 架构, 信息服务 接口(interface)在应用层中声明(这里假设 InfServ 永远不会被域层调用,因此我们决定不在域层中定义 InfServ 接口(interface) - 参见原始 1a 问题),表示应用层控制了 信息服务 界面。但我认为如果基础设施层控制 会更好。信息服务 接口(interface),由于原 中所述的原因2b 题?!
    4)

    It appears the author is implying that since dependencies are only inwardsand since Infrastructure interfaces are defined around Domain Model,that code within Domain Model shouldn't reference these interfaces.


    在我看来,您的代码示例适合编码。

    所以我说洋葱架构不“允许”域模型引用基础设施接口(interface)是正确的,因为它们是在层 中定义的。英德 ( InDe 当然也驻留在应用程序核心中)围绕 DM 强文本并从 引用它们DM 意味着依赖关系从 向上DM 英德 ?

    DDD is typically presented in a hexagonal/onion architectural stylewhich is why there may be some confusion. I think what you've probablybeen doing is already hexagonal which is why it seems like it is thesame thing.


    是的,我也有这种印象。尽管我确实计划在读完 Evan 的书后更深入地研究 Hexagonal 架构(特别是因为新的 DDD 书将基于它的一些示例)。
    第四次更新:
    2)
    d)

    If infrastructure owned interface and implementation then the domainor application layer would be responsible for implementing persistencefor itself.


    我假设应用程序或域层需要自己实现它,因为引用在基础设施层中定义的接口(interface)会洋葱的内层规则不依赖于外层(基础设施层是外层)?
    4)

    Domain model can reference infrastructure interfaces, such as arepository, because they are declared together. If application layeris split from the domain, as it is in the Onion diagram, then the domain layercan avoid referencing interfaces because they can be defined in theapplication layer.


    但是根据那篇文章,基础设施接口(interface)是在围绕域层的层中声明的,这意味着它比域层更接近应用程序核心的外边缘——而且正如文章所指出的,内层不应该依赖于外层>!
    谢谢你

    最佳答案

    1a) 是的,但是域层的定义可以包括充当 facade 的应用程序服务在域上。应用程序服务通常引用存储库和其他基础设施服务。它编排域对象和所述服务以实现用例。

    2a,b)

    如上所述,我通常将应用程序服务合并到域层中。我倾向于坚持Hexagonal architecture样式,也称为端口和适配器。域位于中心,由应用程序服务和所有外部连接(包括存储库、UI 和服务作为端口)封装。

    2c) 在域层声明存储库接口(interface)的部分好处是它指定了域的数据访问要求。

    更新

    1a) 我不打算将我提到的应用程序服务与“常规”应用程序服务区分开来。如果它是域上的外观,则适用规则。

    1b) 可能有些服务仍可称为应用程序服务,但与域没有直接关系,我想排除这些服务。

    2a) 如果您所谓的“常规”应用程序服务与域交互,我认为将其作为域“层”的一部分是可以接受的。但是,域不应直接依赖于周围的应用程序服务,因此如果需要,可以将它们拆分为单独的模块。

    2b) 是的,因为它可以与分层架构形成对比。一个严格的分层架构并不符合在域层中声明存储库接口(interface)并在基础设施层中实现的想法。这是因为一方面您在一个方向上有依赖性,但就部署而言,依赖性在另一方面。 Hexagonal 通过将域置于中心来解决这些问题。看看onion architecture - 它本质上是六边形,但可能更容易掌握。

    2c) 是的,但通常存储库接口(interface)会被应用程序服务引用。

    更新 2

    2a) 它们可以以不同的方式实现,但一般职责是相同的。主要区别在于依赖图。虽然您可以使用任一架构将应用程序服务分离到它们自己的模块中,但洋葱/六边形架构强调使用接口(interface)来声明对基础设施的依赖关系。

    2ba) 是的,这实际上是洋葱架构的一个特征。

    b) 是的。在 TLA 中,域层将根据基础设施层声明的类直接与基础设施通信,而不是相反。

    c) 是的,基础设施实现了领域层声明的接口(interface)。

    d) 耦合是双向的。应用程序核心依赖于基础设施中的实现,基础设施依赖于应用程序核心中声明的接口(interface)。

    4)在我看来,您的代码示例是合适的代码。在某些情况下,实体需要访问存储库才能执行某些操作。但是,为了改善此代码的耦合特性,最好定义一个特定的接口(interface)来声明实体所需的功能,或者如果 lambdas 可用甚至更好。然后,存储库可以实现该接口(interface),应用程序服务将在调用给定行为时将存储库传递给实体。这样,实体不依赖于通用存储库接口(interface),而是依赖于非常具体的角色。

    DDD 通常以六边形/洋葱式架构风格呈现,这就是为什么可能会有一些混淆的原因。我认为您可能一直在做的事情已经是六边形的,这就是为什么它看起来是一样的。

    更新 3

    2b) 在 TLA 中不会有接口(interface),或者不是同一种。该域将直接与基础设施(例如持久性框架)通信,因此它将负责持久性。

    2d) 如果基础设施拥有接口(interface)和实现,那么域或应用层将负责为它自己实现持久性。在六角形/洋葱中,持久性的实现是基础设施的一部分——它使抽象域“适应”数据库。

    4)领域模型可以引用基础设施接口(interface),例如存储库,因为它们是一起声明的。如果应用层从域中分离出来,就像洋葱图中的那样,那么域层可以避免引用接口(interface),因为它们可以在应用层中定义。

    更新 4

    2d) 该声明不适用于具有层次结构的分层架构,例如:UI -> 业务逻辑 -> 数据访问。业务逻辑层依赖于数据访问层,必须基于数据访问框架的对象模型来实现其数据访问。数据访问框架本身对业务层一无所知。

    4) 这篇文章只指定了一种可能的架构。存在可接受的变化。

    关于domain-driven-design - 应用层和基础设施层之间的依赖关系有些困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14589641/

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