DDD设计理解

DDD design understanding

我已经开始学习 DDD,我有几个问题可以提高我对它的理解。

所以典型的 DDD 架构如下所示

领域层 => 该层应该与技术无关,并且应该包含以下内容

Domain.Entities(与持久层实体不同,应该只包含验证规则?其他域业务应该放这里吗?)

Domain.ValueObjects(不需要在域中唯一的对象,应该只包含验证规则)

Domain.Services(这一层应该包含业务逻辑,虽然与聚合相关,但不适合聚合本身。用于需要多个操作的编排器 Domain.Entities and/or Domain.ValueObjects一起合作)

Domain.Factories(这一层不知何故没有被完全理解,我的意思是它的职责是创建聚合或什么?)它是纯粹的工厂设计模式还是与它不同?

Domain.Repositories(这一层也是模棱两可的,除了我知道这一层负责与外部服务通信,它应该处理什么类型的业务逻辑?)

反腐败层(这一层应该充当领域层和应用层之间的网关,它应该负责将响应和请求从一层到另一层的翻译)

应用层 => 应该只用于以易于客户端理解的格式公开数据。过滤在这一层完成 (Linq-To-SQL) / (Linq-To-Entity)

客户端(最后一层)=> 应该没有任何逻辑,只公开应用层服务提供的模型。

我看到的其他图层

Shared.Kernel(Domain.ValueObjects / Domain.Entites(不是 AggregateRoots)在多个限界上下文之间共享)

Infrastructure.Domain.Common(在整个域中共享,例如 AggregateRoot、BaseEntity、BaseValueObject 等)

Infrastructure.DataAccess.Provider(例如 EntityFramework / nHibernate/ MongoDriver ,这一层应该与谁通信?应用层?

DDD 没有定义分层方法。它只是建议使用一个。我建议阅读 Clean/Hexagonal/Onion 分层。这种方法与 DDD 一致并得到广泛认可。

Hexagonal

Clean

Onion

不要被不同的名称所迷惑,方法即使不完全相同也非常相似。

老实说,领域驱动设计的前提会因应用程序要求、业务使命和可能决定应用程序的底层架构而异。领域驱动设计的最简单解读

  • 数据层:抽象的数据层,关注点与图形用户界面的分离。

  • 领域层:您的业务规则和逻辑,公司要求、使命的基础。

  • 服务层:不是必需的,但充当图形用户界面和数据层之间的中介。建模数据与业务实体之间清晰简洁的转换。

  • 应用层:您的用户界面,以有意义的方式为用户提供核心业务功能。

重要的概念,没有一层相互依赖。他们都是独立的,并且互相恭维。您已经涉足了更具体的上下文概念,但并非所有应用程序都相关或可行。

根据您的示例,您可能会向外抽象您的领域,以至于该层可能贫乏,没有包含足够的相关或有用信息。传统的分层应用程序,如果以微服务方法、循环方法(干净的架构)或分层方法编写,则可以是域驱动设计。因为每种方法或风格都在使用领域驱动设计的基本目的,捕捉业务目的和使命。

应用程序不是域驱动设计,因为您有一个层。您的应用程序将遵循一系列原则以符合领域驱动设计。这些原则是为了确保您的应用程序适应业务转变。持有代表业务的核心逻辑,同时随着业务目标在公司整个生命周期中的变化而变化。他们经常落到松耦合的一边。

您提到的上述层中有一半是解决问题的复杂模式。所有的工具都有一个目的,就像一个模式,螺丝刀用于解决问题 x,工厂可以解决 x,但存储库可以解决 y。并非每种图案都适合每种用途。它们不是解决问题的千篇一律的解决方案。

很多 material 关于这个主题。福勒、埃文斯、沃恩和无数其他人。

DDD开始的地方是"the blue book":Domain Driven Design by Eric Evans

a typical DDD architecture looks like

a layered architecture。 Evans 概括了四个概念层

  • 用户界面
  • 申请
  • 基础设施

在第 4 章(隔离域)中,Evans 指出

The part of the software that specifically solves problems from the domain usually constitutes only a small portion of the entire software system, although its importance is disproportionate to its size. To apply our best thinking, we need to be able to look at the elements of our model and see them as a system.... We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether....

在 "domain layer" 中,Evans 认识到两套不同的问题。

域实体、值对象和域服务为软件中的业务建模(第 5 章)。换句话说,这些元素为您的领域专家所认可的概念建模。

存储库和工厂是生命周期问题 - 并不像专家认为的那样与业务严格相关,而是充当应用程序层和领域层之间的边界。

在 Evan 的表述中,业务规则的验证通常存在于域实体(而非域服务)中。正如 OO 样式中常见的那样,域实体结合了状态(域值)和行为(更改规则)——对持久层实体的任何更改(你是对的,不是同一件事)都是由于域执行的代码而发生的实体。

Anti corruption layers 更多关于与外部数据源(可能是遗留系统)集成,然后他们是关于与应用程序层集成。

Implement a façade or adapter layer between a modern application and a legacy system that it depends on. This layer translates requests between the modern application and the legacy system. Use this pattern to ensure that an application's design is not limited by dependencies on legacy systems.

您可能想要查看 github 上提供的 DDD 示例应用程序。这是不同部分如何组合在一起的一个不错的草图。

注意:如今,分层架构已经输给了其他一些替代方案,我们开始看到更多的工作是用功能核心(而不是 OO 风格)来实现领域模型。