领域驱动设计概念解释
复杂性挑战
领域驱动设计中的重要术语
领域驱动设计示例
领域驱动设计的优势
领域驱动设计的缺点
结论
使用微服务意味着通过松散耦合的服务创建应用程序。该应用程序由多个小型服务组成,每个服务代表一个独立的业务目标。它们可以单独开发和轻松维护,然后组合成一个复杂的应用程序。
微服务是一种具有特定有界上下文、配置和依赖关系的架构设计模型。这些理念源自领域驱动设计和 DevOps 的架构原则。领域驱动设计是通过代码解决组织问题的理念。
业务目标对业务用户来说很重要,并且接口和功能清晰。这样,微服务就可以独立于其他微服务运行。此外,团队也可以独立地处理它,这实际上就是微服务架构的意义所在。
许多开发者声称微服务提高了他们的效率。这得益于小团队协作的能力。这使得他们可以开发不同的小组件,然后将它们合并成一个大型应用程序。
他们花费更少的时间与其他开发人员协调,而将更多时间用于开发实际代码。最终,这为最终用户创造了更多价值。
复杂性挑战
复杂性是一个相对的概念。对一个人来说复杂的事情,对另一个人来说可能很简单。然而,复杂性正是领域驱动设计应该解决的问题。在这种情况下,复杂性意味着互联互通、众多不同的数据源、不同的业务目标等等。
领域驱动方法旨在解决软件开发的复杂性。另一方面,当挑战简单时,你可以使用涌现式设计。然而,当你的应用程序很复杂时,复杂性只会增加,你的问题也会随之增加。
领域驱动设计基于业务领域。现代商业环境非常复杂,错误的举动可能会导致致命的后果。领域驱动设计解决了复杂的领域模型,并连接核心业务概念。
Eric Evans 于 2004 年在其著作《领域驱动设计:解决软件核心复杂性》中提出了这一概念。书中指出,领域驱动设计主要关注三个原则:
- 该项目的主要焦点是核心领域和领域逻辑。
- 复杂的设计基于领域模型。
- 技术专家和领域专家之间的协作对于创建解决特定领域问题的应用程序模型至关重要。
领域驱动设计中的重要术语
在 DDD 中,需要注意以下术语:
领域逻辑
领域逻辑是建模的目的。通常,它被称为业务逻辑。业务规则定义了数据的创建、存储和修改方式。
领域模型
领域模型包含围绕您要解决的问题的想法、知识、数据、指标和目标。它包含所有帮助您处理复杂业务逻辑的规则和模式。此外,它们还有助于满足您的业务需求。
子域名
一个域名由多个子域名组成,这些子域名分别指向业务逻辑的不同部分。例如,一家在线零售商店的子域名可以是产品目录、库存和配送。
设计模式
设计模式的核心在于代码的复用。无论你遇到的问题多么复杂,从事面向对象编程的人可能已经创建了一个可以帮助你解决问题的模式。将问题分解成最初的元素,就能引导你找到解决方案。你通过模式学到的一切,以后都可以运用到你开始使用的任何面向对象语言中。
有界上下文
有界上下文是领域驱动设计的核心模式,它涵盖了应用程序的复杂性。它能够处理大型模型和团队。在定义好域和子域之后,就可以在这里实现代码了。
有界上下文实际上代表了某个子域定义和适用的边界。在这里,特定的子域有意义,而其他子域则没有意义。一个实体在不同的上下文中可以有不同的名称。当有界上下文中的某个子域发生变化时,整个系统不必随之改变。这就是开发人员在上下文之间使用适配器的原因。
无处不在的语言
通用语言是一种方法论,指的是领域专家和开发人员在谈论他们正在处理的领域时使用的相同语言。这是必要的,因为项目可能会因语言混乱而面临严重问题。这是因为领域专家使用他们自己的术语。同时,技术专业人员也使用他们自己的术语来谈论该领域。
日常讨论中使用的术语与代码中使用的术语之间存在差距。因此,有必要定义一套人人都使用的术语。通用语言中的所有术语都是围绕领域模型构建的。
实体
实体是数据和行为的组合,例如用户或产品。它们拥有身份,但用行为来表示数据点。
值对象和聚合
值对象具有属性,但不能独立存在。例如,送货地址可以是一个值对象。大型复杂的系统包含无数的实体和值对象。因此,领域模型需要某种结构。这将把它们放入更易于管理的逻辑组中。这些组称为聚合。它们表示相互连接的对象集合,目标是将它们视为单元。此外,它们还有一个聚合根。这是聚合之外的任何对象可以引用的唯一实体。
领域服务
领域服务是一个附加层,也包含领域逻辑。它是领域模型的一部分,就像实体和值对象一样。同时,应用服务是另一个不包含业务逻辑的层。然而,它的作用是协调应用程序的活动,位于领域模型之上。
存储库
存储库模式是简化数据基础架构的业务实体集合。它将领域模型从基础架构问题中解放出来。分层概念强制了关注点分离。
领域驱动设计示例
以一个电商应用为例,其业务领域是处理订单。当客户想要下单时,他们首先需要浏览产品。然后,他们选择自己想要的商品,确认订单,选择配送方式,并付款。之后,应用会处理客户提供的数据。
因此,用户应用程序将由以下层组成:
用户界面
顾客可以在这里找到下单所需的所有信息。在电商领域,产品就在这里。这一层负责将信息呈现给客户,并解释他们的操作。
应用层
这一层不包含业务逻辑。它是引导用户从一个 UI 屏幕切换到另一个 UI 屏幕的部分。它还与其他系统的应用层交互。它可以执行简单的验证,但不包含与领域相关的逻辑或数据访问。它的目的是组织和委托领域对象来完成它们的工作。此外,它是唯一可与其他有界上下文访问的层。
领域层
业务领域的概念就在这里。这一层包含有关业务案例和业务规则的所有信息。实体也在这里。正如我们之前提到的,实体是数据和行为的组合,例如用户或产品。
它们通过唯一键保证其唯一身份,即使其属性发生变化,身份依然有效。例如,在电商平台中,每个订单都有一个唯一标识符。它必须经过确认和发货等一系列操作才能被视为一个实体。
另一方面,值对象没有唯一标识符。它们表示各种实体可以共享的属性。例如,这可能是不同客户的相同姓氏。
此部分还包含具有已定义操作行为的服务,这些服务不必属于任何领域。但是,它们仍然是业务领域的一部分。这些服务根据通用语言命名。它们不应剥夺实体和值对象的明确责任和操作。客户应该能够使用任何给定的服务实例。该实例在应用程序生命周期内的历史记录不应成为问题。
最重要的是,领域层位于业务应用程序的中心。这意味着它应该与其他层分离。它不应该依赖于其他层或其框架。
基础设施层
该层支持与其他层之间的通信,并可包含UI层的支持库。
领域驱动设计的优势
- 沟通更便捷。得益于通用语言,开发人员和团队之间的沟通变得更加便捷。由于通用语言通常包含开发人员常用的简单术语,因此无需使用复杂的技术术语。
- 更灵活。由于 DDD 是面向对象的,领域相关的一切都基于对象,并且对象是模块化和封闭的。因此,整个系统可以定期进行修改和改进。
- 领域优先于 UI/UX。由于领域是核心概念,开发人员将构建适合特定领域的应用程序。这不会是另一个以界面为中心的应用程序。虽然不应忽略 UX,但使用 DDD 方法意味着产品的目标用户正是与领域直接相关的用户。
领域驱动设计的缺点
- 需要深厚的领域知识。即使是技术最先进的开发团队,也必须至少有一位领域专家,能够精准理解应用程序核心主题领域的特征。有时,开发团队需要几位对该领域了如指掌的成员。
- 包含重复性实践。尽管许多人认为这是一个优势,但领域驱动设计包含许多重复性实践。领域驱动设计鼓励使用持续集成来构建能够在必要时自我调整的强大应用程序。许多组织可能难以适应这些方法。尤其是当他们之前的经验通常与灵活性较低的增长模型(例如瀑布模型)相关时。
- 对于技术含量高的项目,它可能并非最佳选择。领域驱动设计非常适合具有复杂业务逻辑的应用程序。然而,对于领域复杂度较低但技术复杂度较高的应用程序,它可能并非最佳解决方案。技术复杂度高的应用程序对于面向业务的领域专家来说可能极具挑战性。这可能会导致许多限制,并非所有团队成员都能解决。
结论
领域驱动设计是一种解决特定领域模型的软件工程方法。该解决方案通过将执行与关键业务原则联系起来,围绕业务模型展开。
领域专家和开发团队之间的通用术语包括领域逻辑、子领域、有界上下文、上下文映射、领域模型和通用语言,作为协作和改进应用程序模型以及解决任何与领域相关的挑战的方式。
在本文中,我们旨在定义领域驱动设计的核心概念。此外,我们还希望对其进行解释,并分析该方法的优缺点。我们希望以此帮助您判断这种方法是否适合您的业务和应用程序。
与传统架构相比,微服务具有诸多显著优势,包括可扩展性、可访问性和灵活性。此外,由于每个微服务都是松耦合的,且具有统一的责任机制,因此这种方法能够让开发人员保持专注。
文章来源:https://dev.to/microtica/the-concept-of-domain-driven-design-explained-1ccn