DDD 与 N 层(3 层)架构

发布于 2024-09-25 07:01:08 字数 464 浏览 0 评论 0原文

我已经练习 DDD 一段时间了,它分为 4 个不同的层:域、表示、应用程序和基础设施。最近,我向我的一位朋友介绍了 DDD 概念,他认为这引入了不必要的复杂性层(特别是针对接口和 IoC)。通常,在这一点上,我会解释 DDD 的好处——尤其是它的模块化。所有繁重的工作和幕后工作都在基础设施中,如果我想完全改变底层数据访问方法,我只需接触基础设施层存储库就可以做到这一点。

我朋友的论点是,他可以用相同的方式构建一个三层应用程序:

  • 业务
  • 数据
  • 表示

他将创建业务模型(如域模型)并让数据层中的存储库返回这些业务模型。然后他会调用业务层,业务层又调用数据层。我告诉他这种方法的问题是它不可测试。当然,您可以编写集成测试,但无法编写真正的单元测试。您能看到他提出的 3 层方法还有其他问题吗(我知道有,否则为什么 DDD 会存在?)。

编辑:他没有使用 IoC。他的示例中的每一层都相互依赖。

I have been practicing DDD for a while now with the 4 distinct layers: Domain, Presentation, Application, and Infrastructure. Recently, I introduced a friend of mine to the DDD concept and he thought it introduced an unnecessary layer of complexity (specifically targeting interfaces and IoC). Usually, its at this point, I explain the benefits of DDD-- especially, its modularity. All the heavy lifting and under the hood stuff is in the Infrastructure and if I wanted to completely change the underlying data-access method, I could do so with only having to touch the Infrastructure layer repository.

My friend's argument is that he could build a three tiered application in the same way:

  • Business
  • Data
  • Presentation

He would create business models (like domain models) and have the repositories in the Data layer return those Business models. Then he would call the business layer which called the data layer. I told him the problem with that approach is that it is not testable. Sure, you can write integration tests, but you can't write true unit tests. Can you see any other problems with his proposed 3-tiered approach (I know there is, because why would DDD exist otherwise?).

EDIT: He is not using IoC. Each layer in his example is dependent on one another.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回心转意 2024-10-02 07:01:09

阅读“软件架构基础:工程方法”,第 8 章,第 100 至 107 页。

架构师对顶层分区特别感兴趣,因为它定义了基本架构风格和分区代码的方式。这是建筑师必须做出的首要决定之一。这两种风格(DDD 和分层)代表了对架构进行顶层划分的不同方式。因此,您在这里不是比较苹果和橙子

使用技术分区的架构师根据技术功能来组织系统的组件:表示、业务规则、持久性等。

域分区,灵感来自 Eric Evan 的《领域驱动设计》一书,它是一种用于分解复杂软件系统的建模技术。在 DDD 中,架构师识别彼此独立且解耦的域或工作流程。

域分区(DDD)可以使用持久性库并具有单独的业务规则层,但顶层分区围绕域。域分区中的每个组件可能有子组件,包括层,但顶级分区侧重于域,这可以更好地反映项目中最常发生的更改类型。

因此,您可以在 DDD 的每个组件上实现层(您的朋友正在做相反的事情,这很有趣,我们也可以尝试一下)。

但是,请注意(“软件架构基础:一种工程方法”,第 135 页)

分层架构是一种技术上分区的架构(如
与域分区架构相反)。组件组,
不是按域(例如客户)分组,而是按
他们在架构中的技术角色(例如演示或
商业)。结果,任何特定的业务领域都被传播
贯穿架构的所有层。例如,
“客户”的领域包含在表示层、业务
层、规则层、服务层和数据库层,使其成为
很难将更改应用于该域。结果,一个
领域驱动设计方法不适用于分层设计
架构风格。

建筑中的一切都是一种权衡,这就是为什么宇宙中每个建筑问题的著名答案都是“视情况而定”。话虽这么说,你朋友的方法的缺点是,它在数据级别具有更高的耦合性。此外,如果架构师后来想要将该架构迁移到分布式系统(例如微服务),那么在理清数据关系时会遇到困难。

Read "Fundamentals of Software Architecture: An Engineering Approach", Chapter 8, Page 100 to 107.

The top-level partitioning is of particular interest to architects because it defines the fundamental architecture style and way of partitioning code. It is one of the first decisions an architect must make. These two styles (DDD & Layered) represent different ways to top-level partition the architecture. So, you are not comparing apples and oranges here.

Architects using technical partitioning organize the components of the system by technical capabilities: presentation, business rules, persistence, and so on.

Domain partitioning, inspired by the Eric Evan book Domain-Driven Design, which is a modeling technique for decomposing complex software systems. In DDD, the architect identifies domains or workflows independent and decoupled from each other.

The domain partitioning (DDD) may use a persistence library and have a separate layer for business rules, but the top-level partitioning revolves around domains. Each component in the domain partitioning may have subcomponents, including layers, but the top-level partitioning focuses on domains, which better reflects the kinds of changes that most often occur on projects.

So you can implement layers on each component of DDD (your friend is doing the opposite, which is interesting and we might try that out as well).

However, please note that ("Fundamentals of Software Architecture: An Engineering Approach", Page 135)

The layered architecture is a technically partitioned architecture (as
opposed to a domain-partitioned architecture). Groups of components,
rather than being grouped by domain (such as customer), are grouped by
their technical role in the architecture (such as presentation or
business). As a result, any particular business domain is spread
throughout all of the layers of the architecture. For example, the
domain of “customer” is contained in the presentation layer, business
layer, rules layer, services layer, and database layer, making it
difficult to apply changes to that domain. As a result, a
domain-driven design approach does not work as well with the layered
architecture style.

Everything in architecture is a trade-off, which is why the famous answer to every architecture question in the universe is “it depends.” Being said that, the disadvantage with your friend's approach is, it has higher coupling at the data level. Moreover, it will creates difficulties in untangling the data relationships if the architects later want to migrate this architecture to a distributed system (ex. microservices).

断念 2024-10-02 07:01:09

N 层或本例中的 3 层架构非常适合单元测试。
您所要做的就是使用依赖注入和存储库模式进行 IoC(控制反转)。

业务层可以验证并通过返回所需的确切数据来为演示\Web API 层准备返回的数据。
然后,您可以在单元测试中一直使用模拟。
你所有的业务逻辑和需求都可以在BL层上。 Dal 层将包含从更高级别注入的存储库。

N Tier or in this case 3-tier architecture is working great with unit tests .
All you have to do is IoC (inversion of control) using dependency injection and repository pattern .

The business layer can validate , and prepare the returned data for the presentation \ web api layer by returning the exact data which is required .
You can then use mock in you unit tests all the way through the layers.
All your business logic and needs can be on bl layer . And Dal layer will contain repositories injected from higher level.

仅一夜美梦 2024-10-02 07:01:08

我认为你正在比较苹果和橘子。 N-Tier 没有任何内容禁止它使用接口和接口。 DI 以便轻松进行单元测试。同样,DDD 可以通过静态类和硬依赖来完成。

此外,如果他正在实现业务对象并使用存储库,听起来他正在做 DDD,而您只是在争论语义。

您确定问题不仅仅在于使用 DI/IoC 吗?

I think you're comparing apples and oranges. Nothing about N-Tier prohibits it from utilizing interfaces & DI in order to be easily unit-tested. Likewise, DDD can be done with static classes and hard dependencies.

Furthermore, if he's implementing business objects and using Repositories, it sounds like he IS doing DDD, and you are quibbling over little more than semantics.

Are you sure the issue isn't simply over using DI/IoC or not?

少女净妖师 2024-10-02 07:01:08

我认为你混合了一些方法。 DDD 是领域驱动开发,旨在使业务领域成为代码的一部分。您所描述的内容听起来更像是洋葱架构(链接)而不是“正常”的三层方法。使用 3 层架构和 DDD 并没有什么问题。 DDD 依赖于 TDD(测试驱动开发)。接口有助于 TDD,因为更容易单独测试每个类。如果您使用依赖注入(和 IoC),它会进一步缓解。

洋葱架构旨在使域(又名业务规则)独立于其他一切 - 即。它是应用程序的核心,一切都取决于业务对象和规则,而与基础设施、UI 等相关的东西则位于外层。这个想法是,模块越接近“洋葱壳”,就越容易更换新的实现。

希望这能澄清一点——现在进行一些小的编辑!

I think you are mixing a few methodologies up. DDD is Domain-Driven Developement and is about making the business domain a part of your code. What you are describing sounds more like the Onion Architecture (link) versus a 'normal' 3-layered approach. There is nothing wrong with using a 3-layered architecture with DDD. DDD depends on TDD (TestDriven Developement). Interfaces help with TDD as it is easier to test each class in isolation. If you use Dependency Injection (and IoC) it is further mitigated.

The Onion Architecture is about making the Domain (a.k.a. business rules) independent of everything else - ie. it's the core of the application with everything depending on the business objects and rules while things related to infrastructure, UI and so on are in the outer layers. The idea is that the closer to the 'shell of the onion' a module is - the easier it is to exchange for a new implementation.

Hope this clears it a bit up - now with a minor edit!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文