楼主: 苏东坡0321
43 0

[作业] DDD 概念理解-理论篇 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-4-19
最后登录
2018-4-19

楼主
苏东坡0321 发表于 2025-12-9 07:01:20 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

本文为DDD理论解析篇,旨在清晰阐述领域驱动设计(Domain Driven Design,简称DDD)的核心理念、基本思想及其主要内容。希望通过本文的阅读,读者能够对DDD形成系统性的理解。

关于DDD在实际项目中的代码结构与工程实践,敬请期待后续内容更新。

1. 什么是DDD?

1.1 DDD的基本定义

领域驱动设计(Domain Driven Design,DDD)是一种兼顾业务逻辑与技术实现的架构设计方法论。它贯穿从业务需求分析到领域建模,再到技术服务落地的全过程,强调开发人员与领域专家之间的紧密协作。

其核心理念在于实现业务与技术的深度融合——不仅重视对业务本质的深入理解,也注重运用科学的建模手段进行系统化抽象。从本质上讲,DDD是面向对象分析方法的深化与拓展,通过分层架构设计和明确的概念划分,提供了更为完整和严谨的思维框架。(可理解为一种更高级、更全面的面向对象思维方式)

通俗来说,DDD的作用就是将现实世界中高度复杂的业务问题进行清晰边界划分和结构化梳理,帮助开发团队依据业务特征合理地进行系统、应用及模块的拆解,从而更好地应对业务变化,控制需求波动,并有效限制代码修改的影响范围。

1.2 为什么需要DDD?

对于架构师而言,如何有效降低系统的复杂度始终是软件开发中的核心挑战。无论是构建业务系统、平台服务还是中台能力,团队常常面临以下困境:

  • 系统复杂度高:业务系统庞大且相互关联,扩展性差,概念模糊,逻辑交错,缺乏清晰的方法指导我们界定边界、理清逻辑。
  • 多团队协作困难:模块之间依赖严重,改动牵一发而动全身,职责边界不清晰,且不同角色使用不同的术语沟通,造成理解偏差。例如,“航程”是否在所有人认知中含义一致?是否存在统一的语言体系来消除歧义?
  • 设计与实现脱节:产品文档(PRD)、详细设计方案与最终代码实现存在巨大差异。一个业务变更往往引发上下游大量代码调整,难以快速将业务需求转化为稳定设计并保持一致性。
  • 架构复用性不足:当前系统抽象能力高度依赖个别开发者的技术水平和经验,缺乏标准化方法支持团队整体进行高质量的模型抽象与可复用组件建设。

解决方案:DDD的本质正是应对软件复杂性的有力工具。它通过领域建模,在战略层面统一业务语言,在战术层面确保代码结构反映业务逻辑,从而实现“业务演进带动技术演进”的目标。随着业务的发展,系统能够精准控制变更影响范围,提升可维护性和扩展能力,显著缓解上述各类问题。

1.3 何时适用DDD?

DDD主要用于解决那些业务模型极其复杂、业务复杂性远超技术实现难度的项目场景。因此,是否引入DDD,关键在于判断系统的业务复杂程度。

如果您的系统具备如下特征:

  • 以数据为中心,主要操作为数据库的增删改查(CRUD);
  • 仅涉及少量简单的业务场景或用例;
  • 功能相对稳定,变动频率低;
  • 团队对该业务领域已有充分认知。

那么,采用传统的面向数据架构或事务脚本模式即可满足需求。

然而,当业务逻辑复杂、频繁变更,且团队对领域知识尚不充分时,就需要借助DDD来进行系统的领域建模与服务划分,以实现有效的抽象与问题求解。

1.4 DDD如何解决问题?

DDD通过两个关键维度——战略设计战术设计,实现从业务到代码的一致性映射。

  • 战略设计:从宏观业务视角出发,识别核心业务领域,建立清晰的领域模型,划分限界上下文,并构建团队共用的通用语言。这些成果可作为微服务划分的重要参考依据。
  • 战术设计:聚焦技术实现层面,围绕领域模型进行具体编码落地,包括聚合根、实体、值对象、领域服务、应用服务以及资源库等元素的设计与组织。

在战略设计中,构建准确的领域模型是重中之重。为此,DDD提出了一种高效建模方法——事件风暴。该方法经历一个从发散到收敛的过程:

  • 初期通过用例分析、场景模拟和用户旅程梳理,全面挖掘业务细节,识别出大量的命令、事件和实体等元素;
  • 随后对这些元素按业务语义进行聚类,逐步形成聚合、限界上下文等结构单元,完成模型的收敛与定型。

由此可见,DDD有助于工程师建立结构清晰的领域模型,明确业务与应用的边界,进而指导微服务的合理拆分。事件风暴作为核心建模手段,通过“发散+聚合”的双阶段过程,助力团队构建科学合理的领域模型,推动高效开发与顺利落地。

2. DDD核心概念解析

2.1 战略设计要点

2.1.1 统一语言(Ubiquitous Language)

在事件风暴过程中,开发团队与领域专家共同协商形成的、能够简洁、准确表达业务含义与规则的语言,被称为通用语言。这种语言是整个团队的统一沟通工具,无论成员角色如何,在项目的全生命周期中都应使用同一套术语进行交流。

软件所实现的模型本质上就是通用语言的体现,源代码即是该语言的书面表达形式。因此,通用语言必须具备严谨性、精确性和简洁性。

建立统一语言的意义在于消除沟通障碍,提升协作效率,保障业务需求被正确理解和系统被准确实现。

2.1.2 领域(Domain)

“领域”指软件所要解决的核心业务问题空间。它是业务背景下的特定范围,涵盖了相关的流程、规则、参与者和目标。DDD强调深入理解该领域,并围绕其构建相应的模型与系统结构。

在领域驱动设计(DDD)中,领域指的是某个业务问题的整体背景与环境。它涵盖了相关的业务逻辑、规则、流程以及核心概念,是软件系统需要实现和应对的业务内容的抽象表达。

从字面理解,“领域”是指某一专门活动或事业的范围、类别或部门,具体表现为一个特定的区域或范畴。既然是范围,就必然存在边界。因此,划分领域的过程本质上就是确立边界的实践。

DDD 中的“领域”,特指在这一边界内所要解决的业务问题空间。为有效处理复杂的业务场景,DDD 会依据一定的策略对整体业务领域进行拆分。当领域被逐步细化后,问题的讨论范围将被限制在一个明确的边界之内。在此基础上构建领域模型,并通过代码加以实现,从而精准地解决对应的业务问题。

由于领域用于界定业务的边界与范围,其本身具有大小之分:领域越大,涵盖的业务范围越广;反之则越聚焦。同时,一个大的领域可以进一步划分为多个子领域,这些细分后的部分被称为子域。每个子域对应一个更小的问题空间或更具体的业务职能。复杂系统中往往包含多个子域,分别承担不同的业务职责。

2.1.2.1. 子域

子域(Subdomain)是对主领域的进一步分解,代表某一特定业务功能或流程的子集。每一个子域都聚焦于一个更狭窄的问题域或业务范围。根据其在企业中的重要性与特性,子域通常可分为三类:

  • 核心子域(Core Subdomain):承载企业最重要的业务能力,具备强烈的业务属性和企业特色,直接决定产品或企业的核心竞争力。例如,在保险行业中,承保、收付、理赔等环节即为核心子域,如同一棵树上的果实与花朵——是价值产出的关键部位。
  • 通用子域(Generic Subdomain):属于高度通用的功能模块,个性化需求较少,不具备显著的企业特征,且可被多个子域复用,甚至可通过采购第三方服务获得。如用户认证、权限管理等功能即属此类。
  • 支撑子域(Supporting Subdomain):虽具一定企业特性,但业务属性较弱,也不具备广泛通用性,却是企业运营所必需的基础支持系统。例如数据字典管理系统,类似于树木的茎与叶,虽不直接结果,但参与养分输送,也可能与核心部分争夺资源。

在依赖关系上,核心子域可以引用通用子域和支撑子域的服务,但反向依赖不被允许,以保障核心逻辑的独立性和稳定性。

2.1.3. 限界上下文

“限界上下文”由两个关键词组成:限界上下文

限界 指的是具体的领域边界,明确了哪些内容属于该领域,哪些不属于;上下文 则强调语义环境,即术语在特定业务场景下的含义。例如在电商系统中,同一个物品在销售阶段称为“商品”,在物流阶段则称为“货物”。尽管实体相同,但由于所处的业务阶段不同,其命名与行为也随之变化,这正是上下文影响语义的体现。

综上所述,限界上下文 是在明确的边界范围内,封装通用语言和领域对象的一种机制,确保领域内的术语、概念和模型元素具有唯一、清晰的定义,避免语义歧义。它不仅划定了领域模型的应用边界,也规范了模型的使用范围,为团队成员提供统一的认知框架,指导哪些内容应纳入模型,哪些应排除在外,从而维护模型的一致性与完整性。

举例来说:

企业在设置组织架构时(如设立“人力资源部”、“财务部”、“后勤部”等部门),实际上就是在定义各自的限界上下文边界。这种划分基于职能分工,明确各部门的责任范围。部门内部聚集与其职能相关的所有角色,这些角色类似于领域模型中的领域对象。

一旦确定了部门的职责边界,就不应出现职能重叠或混淆的情况,也不能将无关职能的角色纳入其中,否则将破坏该组织单元的上下文一致性。换句话说:

  • 限界 —— 确定领域边界的规则,在领域模型图中表现为领域之间的分隔线;
  • 上下文 —— 边界内部的业务语境与运行规则,决定了术语和对象的具体含义。

2.1.3.1. 上下文映射

上下文映射(Context Mapping) 描述的是多个不同的限界上下文之间,在解决方案空间中如何通过集成形成相互关联与协作的关系。它帮助团队理解各子系统间的交互方式、数据流向及依赖结构,是协调复杂系统演进的重要工具。

2.2. 战术设计

2.2.1. 实体

实体(Entity)与值对象共同构成领域模型的基本组成部分。

实体 是一种具有唯一身份标识的对象,其身份在整个生命周期中保持不变。对于实体而言,关键在于它的标识而非具体属性。即使属性发生变更,只要标识未变,仍视为同一实体。这种标识往往跨越软件系统的生命周期,甚至延伸至现实世界的业务流程中。

典型的实体包括:订单、用户等。简言之,实体的身份是恒定的,而其属性是可以动态变化的。

实体在不同阶段呈现不同的形态:

  • 业务形态: 在战略设计层面,实体表现为一组聚合的属性、操作或行为的整体,是响应命令、事件或业务动作的核心载体。
  • 代码形态: 在战术设计中,实体以类的形式存在,采用充血模型,封装自身的属性与行为方法。跨实体的复杂业务逻辑则交由领域服务处理。
  • 运行形态: 作为领域对象(DO)的实例存在于内存中,属性可多次修改,但由于 ID 不变,始终代表同一个业务实体。
  • 存储形态: 一个领域对象(DO)可能对应零个、一个或多个数据持久化对象(PO)。PO 更侧重于数据库性能优化,与 DO 的设计并非严格一一对应,两者之间解耦设计更为灵活。

2.2.2. 值对象

相较于实体,值对象 更加抽象,不具备唯一身份标识。

值对象的关注点在于其所包含的属性值的组合,而不是其身份。只要两个值对象的属性值完全一致,即可认为它们相等。因此,值对象常用于描述那些仅通过值来定义的概念,如地址、金额、颜色等。

值对象是一种描述领域中特定概念的模型元素,通常不具备唯一标识,而是通过其属性值来判断相等性。它将多个相关的属性组合成一个具有整体意义的概念单元,用于表达如货币、地址等无独立身份的数据结构。

从本质上讲,值对象可以被视为一个集合。该集合包含若干个用于描述某一业务语义、具备完整概念且不可变的属性。例如,“地址”作为一个常见的值对象,由“省、市、县、街道”等多个字段共同构成一个逻辑整体——这个整体即为地址值对象。

值对象在不同阶段的表现形态

业务形态: 在战略设计层面,值对象与实体类似,表现为一组相关属性的聚合,但不包含独立的身份标识或核心业务行为逻辑。

代码形态: 在战术设计中,值对象通常作为实体类中的一个成员属性存在,自身没有唯一ID,并被整个实体所引用和管理。

运行形态: 在系统运行时,值对象以领域对象(DO)的成员变量形式存在,主要用于数据承载,不涉及对状态的修改操作。

存储形态: 在数据持久化过程中,值对象往往作为嵌入式属性保存在所属实体对应的数据库表中,多数情况下会存放在扩展字段(如JSON类型字段)内。

提示: 当一个对象通过其身份标识(而非属性)进行区分时,称为实体(Entity);而当一个对象仅用于描述事务特征、不具备唯一标识时,则被称为值对象(Value Object)。

2.2.3 聚合(Aggregate)

实体和值对象都是个体化的领域模型元素,体现的是单一对象的行为与能力。为了实现更复杂的业务场景,需要将这些相互关联的对象组织起来,形成一个遵循统一规则的整体协作单元,这就是“聚合”的由来。聚合代表的是整体性的业务能力。

聚合(Aggregate) 是由业务上紧密关联的实体和值对象组成的集合。在聚合内部,所有数据的变更必须由聚合根统一协调,确保每一次修改都符合既定的业务规则。聚合是数据修改和持久化的最小一致性单元。

传统数据建模方式允许直接基于表结构或任意实体进行数据操作,但在领域驱动设计(DDD)中,这种做法被禁止。所有的写操作必须通过聚合根发起,以保障聚合内数据的一致性和完整性。

聚合的设计目标在于维护业务数据的正确状态,同时降低对象间关系的复杂度。每个聚合必须包含一个聚合根,作为整个聚合的控制中心。此外,每个聚合应配备一个仓储(Repository),用于完成该聚合整体的数据持久化。为减少频繁更新带来的性能问题,建议将聚合内的变更封装在一次事务提交中处理。

举例说明:订单聚合拥有一条明确的业务规则——“订单总金额等于所有商品明细金额之和”。这条规则必须在聚合内部得到强制执行,任何对该聚合的修改都不能破坏这一约束。

2.2.4 聚合根(Aggregate Root)

聚合根(Aggregate Root) 是聚合的根节点,是外部访问该聚合的唯一入口。它负责管理聚合内所有对象的生命周期与数据一致性,是一种特殊的实体,承担着对聚合内部结构的统一控制职责。

作为聚合的核心,聚合根本身也是一个实体,通常拥有全局唯一的标识符,用以在整个系统中唯一标识该聚合实例。它是聚合内业务规则的制定者与执行者,确保所有操作都在一致的上下文中完成。

聚合根的主要职责包括:

  • 事务边界定义: 聚合根划定了事务的作用范围,保证聚合内部的操作具有原子性。
  • 身份标识: 每个聚合根都有唯一标识,代表整个聚合的身份。
  • 管理控制: 作为聚合的管理者,协调内部实体与值对象,依据固定业务规则协同完成聚合级业务逻辑。
  • 访问控制: 外部系统只能通过聚合根ID与其交互,无法直接访问聚合内部的其他对象,从而实现封装与解耦。

举个生活中的例子:在班级值日的情境下,一个值日小组可类比为一个聚合,组长则是聚合根。组员各司其职——有人扫地、有人擦黑板、有人擦窗。组长不仅自己参与劳动,更重要的是统筹安排任务。老师若想了解该组的值日进展,只会向组长询问。组长对外代表整个小组,承担最终责任。

聚合的设计原则

作为DDD模型体系中的关键层级,聚合应遵循高内聚、低耦合的基本设计思想。具体而言,聚合设计需满足以下五项核心规则:

  1. 在一致性边界内建模真正的不变条件: 聚合是划分微服务时最小的业务单元,应在边界内维护关键业务规则的恒定成立。
  2. 事务边界: 聚合根定义了事务的边界,确保聚合内部的所有操作要么全部成功,要么全部回滚。
  3. 生命周期一致性: 聚合内的所有对象与聚合根存在强依赖关系。一旦聚合根被删除,其内部所有对象也应随之消失,体现出“共存亡”的特性。
  4. 问题域一致性: 只有属于同一问题域的对象才应归属于同一个聚合。跨领域概念不应强行合并。
  5. 场景频率一致性: 经常被同时读取或修改的对象倾向于属于同一聚合;而极少一起操作的对象则不应放在同一聚合中。

除此之外,还需注意以下实践建议:

  • 设计小聚合: 尽量保持聚合精简,避免包含过多实体和值对象。过大的聚会增加逻辑复杂性,在高并发场景下容易引发锁冲突,影响系统可用性。
  • 通过唯一标识引用其他聚合: 聚合之间应通过引用对方的聚合根ID进行关联,而不是直接持有对象引用。这种方式有利于未来拆分微服务时保持接口稳定。
  • 在边界外使用最终一致性: 在聚合内部采用强一致性策略,而在跨聚合操作中采用最终一致性机制。DDD提倡一次事务只修改一个聚合的数据。若业务流程涉及多个聚合的状态变更,应借助领域事件实现异步解耦。
  • 应用层实现跨聚合的服务调用: 对于跨越多个聚合的业务逻辑,应在应用服务层协调各个聚合之间的交互,确保职责清晰、边界分明。

在领域驱动设计(DDD)中,为了降低聚合之间的耦合度,通常通过应用层的应用服务来协调和组织不同聚合的领域服务。这种方式不仅实现了跨聚合的服务调用,还有效解耦了各聚合间的依赖关系。

2.2.4.1 工厂

为使聚合根能够专注于核心领域模型的职责,在创建DO对象时,需确保聚合根及其内部依赖的对象能被一并初始化。若将这一复杂过程交由聚合根自身完成,其构造函数将变得异常臃肿且难以维护。

当对象或整个聚合的创建过程较为复杂,或会暴露过多内部结构细节时,应引入工厂模式进行封装。即:

将创建复杂对象或聚合的职责转移至一个独立的对象中,该对象虽在领域模型中无具体业务职能,但仍是领域设计的重要组成部分。

工厂的核心作用在于:

  • 封装对象创建所需的全部逻辑
  • 在聚合根实例化的同时,自动构建其所包含的所有子对象

这种实现方式与设计模式中的工厂类和工厂方法理念一致,均旨在隐藏复杂的实例化流程,提升代码的可读性与可维护性。

聚合与领域服务的区别

尽管聚合根和领域服务都能组合多个实体以实现复杂的业务逻辑,但为了避免聚合根承担过多职责,导致类膨胀和逻辑混乱,建议:

  • 聚合根主要负责聚合内的管理职责及与其自身行为直接相关的业务逻辑
  • 跨多个实体的复杂领域逻辑应统一交由领域服务处理

对于简单的聚合,若涉及少量跨实体操作,也可在聚合根的方法中实现,但应谨慎控制其复杂度。

2.2.5 存储库(Repository)

为实现领域逻辑与数据访问逻辑的分离,提升领域层的纯粹性,在领域层与基础设施层之间引入存储库层。

存储库的主要职责包括:

  • 封装对数据库的操作细节
  • 实现领域对象的持久化与重建
  • 解耦业务逻辑与底层数据存储机制

通过提供简洁的接口,存储库使得领域层无需直接操作数据库即可完成数据交互。

每个聚合对应一个存储库,所有对该聚合的数据持久化操作均由该存储库统一处理。

2.2.6 领域事件(Domain Event)

领域事件代表在领域内发生的、具有业务意义的重要操作结果。它的发生往往触发后续一系列业务动作,并有助于形成完整的业务闭环。

设计领域事件的主要目的包括:

  1. 系统解耦
  2. 记录关键业务状态变化
  3. 驱动后续业务流程执行

常见的领域事件示例如下:

  • 用户下单完成后,发布“订单创建事件”
  • 支付成功后,生成“支付完成事件”
  • 店铺草稿提交审核后,触发“草稿提交成功事件”

需要注意的是,领域事件不等同于状态机。前者是业务上可感知的操作结果,具备明确的业务含义;而后者仅是一种技术实现手段。

以店铺系统为例,草稿可能经历多种状态流转,如:[初始化]、[待提单]、[提单失败]、[提单成功]、[审核失败]、[审核成功]、[发布中]、[发布失败]、[发布成功]。其中,仅有部分状态具有实际业务意义,例如:

  • [提单成功] —— 对应草稿提交操作
  • [审核成功] —— 对应审核通过动作
  • [发布成功] —— 表示草稿信息正式生效

虽然多数情况下领域事件伴随实体状态变更,但这并非绝对。例如,“店铺归属关系创建/变更事件”表示某个BD获得管辖权,此事件本身并不引发任何实体状态改变,但仍具重要业务价值。

3. 分层架构

当前主流的微服务架构模型包括“洋葱架构”、“CQRS”、“六边形架构”等,它们共同的设计目标是构建高内聚、低耦合的系统结构,支持灵活的架构演进。

DDD的标准分层架构包含四个层级:

  • User Interface(用户接口层)
  • Application(应用层)
  • Domain(领域层)
  • Infrastructure(基础设施层)

用户接口层(Facade)

负责处理外部请求,完成协议转换与数据格式映射,实现与各类客户端或系统的交互。

应用层

作为轻量级协调层,其核心职责为:

  • 组织和编排多个聚合的协作流程
  • 调用领域服务完成业务任务
  • 订阅并发布领域事件
  • 与外部服务进行通信

应用层本身不包含具体的业务规则,而是将执行逻辑委托给领域层。事件的具体处理逻辑仍定义在领域层中。

领域层

作为整个系统的核心,领域层承载以下关键职能:

  • 表达完整的业务知识体系
  • 掌控业务状态的演进过程
  • 实现企业最核心的业务逻辑

跨聚合的复杂业务逻辑在此层通过领域服务进行组织与协调,确保原子性业务单元得以完整执行。

领域层聚焦于:

  • 构建充血的领域模型
  • 实现聚合内部的原子业务规则

而用户操作流程与服务编排则交由应用层处理,从而保障领域模型不受外部需求波动影响,保持长期稳定。

领域服务(Domain Service)

用于封装那些不属于单一实体、但涉及多个实体协同的业务逻辑。当某项逻辑无法自然归属于某个实体时,可通过领域服务进行抽象。

领域服务通常是无状态的,仅提供行为定义。

基础设施层

为其他各层提供通用的技术支撑与基础能力,涵盖内容包括但不限于:

  • 第三方工具与驱动
  • 消息中间件
  • 网关组件
  • 文件系统
  • 缓存机制
  • 数据库访问层

3.1 传统三层架构向DDD分层架构的演化路径

3.2 不同架构模型的对比分析

3.2.1 六边形架构

六边形架构强调系统核心为业务逻辑,外部依赖通过“端口与适配器”方式进行接入,实现内外解耦。其设计理念与DDD高度契合,有利于测试性和可扩展性的提升。

2008年,Jeffre Palermo 提出了洋葱架构,该架构的核心思想基于严格的依赖原则,明确了各层之间的依赖关系。其设计目标是让内层保持高度独立性,外层则依赖于内层,从而保证核心业务逻辑的稳定性与可维护性。

在洋葱架构中,依赖方向只能由外向内,内层无需了解外层的存在,也不受其影响。这种结构使得越靠近中心的层次,代码抽象程度越高,业务价值越大,同时对外部变化的敏感度越低。

洋葱架构的分层结构:

领域模型层(最内层):
承载企业核心业务规则和逻辑,是整个系统中最稳定、最具价值的部分。该层以实体为核心,实体可以表现为带有行为的对象,也可以是数据与方法的集合,专注于表达真实的业务语义。

领域服务层:
用于处理跨越多个实体的复杂业务操作,封装那些不适合放在单一实体中的业务逻辑,确保领域模型的完整性与一致性。

应用服务层:
负责编排用户操作相关的服务流程,实现具体的用例场景。它不包含核心业务规则,而是协调领域对象和服务来完成特定的应用功能,体现系统的使用流程。

最外层(适配层):
提供对外交互的能力,分为两种适配方式:
- 主动适配:如用户界面、网页前端、批处理任务或自动化测试工具等,作为外部请求进入系统的入口,驱动内部逻辑执行。
- 被动适配:如数据库、缓存、文件系统、消息中间件等基础设施,由核心逻辑通过接口调用这些资源,实际实现由外层提供,遵循依赖倒置原则。

2025年,Alistair Cockburn 提出六边形架构,又称“端口与适配器”架构,强调将系统核心与外部环境完全隔离,所有交互都通过明确定义的端口和适配器进行。

六边形架构的核心理念:
系统的核心业务能力(即图中红圈所示区域)不直接依赖任何外部组件,而是通过适配器与其通信。外部系统无论是前端、第三方服务还是数据存储,都被视为“外部边界”,必须经由适配器接入。

内六边形:
包含应用的核心业务逻辑,独立于具体的技术实现和外部依赖,仅关注业务本身的正确性与完整性。

外六边形:
处理与外部世界的交互,包括前端调用、驱动程序以及各类基础资源的访问。对外部应用采用主动适配的方式暴露 API;对底层资源则采用依赖倒置的方式实现解耦,使核心不必知晓具体实现细节。

领域层的依赖倒置:
传统架构中领域层往往依赖基础设施层,而在此架构中实现了反转——基础设施层反过来依赖领域层所定义的抽象接口。这一转变使得领域层彻底摆脱对外部技术栈的依赖,仅专注于表达纯粹的业务意图,提升了系统的可测试性和可扩展性。

三种架构对比分析:

对比维度\架构类型 DDD 分层架构 洋葱架构 六边形架构
职责划分 三层及以上结构清晰,每层职责明确 各层边界分明,依赖方向严格限定 内外分离,角色定义清晰,适配器承担交互职责
核心焦点 追求各层独立演进与扩展能力 强调领域能力与基础资源解耦,二者均可独立替换 聚焦外部适配器的灵活性,便于扩展与更换
落地与维护成本 相对容易实施,理解门槛较低,通用性强 实施难度较高,依赖倒置机制较反直觉,学习曲线陡峭 实施复杂,关键在于准确识别变与不变的部分,合理划分适配器
适用场景 适用于领域模型复杂、业务逻辑清晰的项目,整体通用性好 适合大型复杂系统,尤其当底层依赖需要频繁更换时 适用于需频繁对接多种外部系统的场景,强调接口开放性与集成能力

参考文献:
《中台架构与实现:基于 DDD 和微服务》,机械工业出版社

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:DDD 理论篇 Application Ubiquitous supporting

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-21 13:04