了解 DDD 设计



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

所以典型的 DDD 体系结构如下所示

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

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

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

Domain.Services(此层应包含业务逻辑,尽管该逻辑与聚合相关,但不适合聚合本身。 业务流程协调程序,用于需要多域.实体和/或域.值对象协同操作的操作)

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

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

防损层(该层应充当域层和应用层之间的网关,它应负责将响应和请求从一层转换为另一层)

应用程序层 => 应仅用于以客户端易于理解的格式公开数据。筛选在此层(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 没有定义分层方法。它只是建议使用一个。我建议阅读清洁/六角形/洋葱分层。这种方法与 DDD 一致并得到广泛认可。

六方

干净

洋葱

不要让不同的名字欺骗你,方法非常相似,如果不是相同的话。

老实说,领域驱动设计的前提将根据应用程序要求、业务任务和可能决定应用程序的底层体系结构而有所不同。 领域驱动设计的最简单的解释。

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

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

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

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

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

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

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

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

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

从DDD开始的地方是"蓝皮书":Eric Evans的领域驱动设计

典型的 DDD 体系结构如下所示

分层架构。 埃文斯回顾了四个概念层

  • 用户界面
  • 应用
  • 基础设施

在第4章(隔离域)中,埃文斯指出

专门解决域问题的软件部分通常只占整个软件系统的一小部分,尽管其重要性与其大小不成比例。 为了应用我们最好的思维,我们需要能够查看模型的元素,并将它们视为一个系统。我们需要将域对象与系统的其他功能分离,这样我们就可以避免将域概念与仅与软件技术相关的其他概念混淆,或者完全忽略域。

在"领域层"中,埃文斯认识到两组不同的关注点。

域实体、值对象和域服务在软件中对业务进行建模(第 5 章)。 换句话说,这些元素对领域专家将识别的概念进行建模。

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

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

防损层更多地涉及与外部数据源(可能是遗留系统)集成,然后是与应用程序层集成。

在现代应用程序与其依赖的旧系统之间实现外观或适配器层。此层在现代应用程序和旧系统之间转换请求。使用此模式可确保应用程序的设计不受旧系统上的依赖关系的限制。

您可能需要查看 github 上提供的 DDD 示例应用程序。 这是一张关于不同部分如何组合在一起的体面草图。

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

最新更新