DDD - 领域驱动设计分层架构:构建可演化的微服务架构

news2025/2/2 2:32:02

文章目录

  • 引言
  • 1. 什么是DDD分层架构?
    • 1.1 DDD分层架构的演变
    • 1.2 四层架构的起源与问题
    • 1.3 依赖倒置和五层架构
  • 2. DDD分层架构的核心层次
    • 2.1 用户接口层(User Interface Layer)
    • 2.2 应用层(Application Layer)
    • 2.3 领域层(Domain Layer)
    • 2.4 基础层(Infrastructure Layer)
  • 3. DDD分层架构的重要原则
    • 3.1 严格分层架构 vs 松散分层架构
    • 3.2 依赖倒置原则(DIP)
  • 4. DDD分层架构的演进
    • 4.1 领域模型与微服务架构的演进
      • 微服务架构的演进
      • 微服务内服务的演进
    • 4.2 从三层架构到DDD分层架构的转型
  • 5. 小结

在这里插入图片描述


引言

随着微服务架构的广泛应用,如何设计一个易于扩展、维护且具备高内聚、低耦合的系统架构成为了开发者和架构师们共同面临的挑战。DDD(领域驱动设计)为这一问题提供了有力的指导,尤其是DDD的分层架构,它通过层次化的设计有效降低了不同层之间的耦合度,提升了系统的灵活性和可演化性。

接下来,我们将详细讨论DDD分层架构的核心思想和设计模式,分析如何将它应用到微服务架构中,并通过具体示例来说明如何从传统三层架构演进到DDD分层架构。我们还会探讨DDD分层架构如何帮助微服务的架构演进,以便应对快速变化的业务需求。

1. 什么是DDD分层架构?

领域驱动设计(Domain-Driven Design,DDD)是一种设计方法论,它强调通过对领域的深入理解,驱动软件的设计与架构。而DDD分层架构是DDD中一种经典的架构模式,它帮助开发者将复杂的业务逻辑分割成不同的层次,每个层次负责不同的职责。通过这种方式,DDD分层架构使得系统的业务逻辑更加清晰,架构的维护与演进也变得更加容易。


1.1 DDD分层架构的演变

DDD分层架构并非一成不变的,它经历了多个版本的演变。从最初的传统四层架构,到后来的五层架构,每次演变都在解决层间依赖、职责划分和架构灵活性的问题。我们先从传统的四层架构开始,逐步了解它是如何通过优化演变为DDD分层架构的。
在这里插入图片描述

在最早的传统四层架构中,基础层是被其它层依赖的,它位于最核心的位置,那按照分层架构的思想,它应该就是核心,但实际上领域层才是软件的核心,所以这种依赖是有问题的。后来我们采用了依赖倒置(Dependency inversionprinciple,DIP)的设计,优化了传统的四层架构,实现了各层对基础层的解耦

1.2 四层架构的起源与问题

最初的四层架构包括:

  1. 用户接口层:负责与外部交互,向用户展示信息。
  2. 应用层:处理业务流程和用例,协调领域层的操作。
  3. 领域层:包含领域模型和核心业务逻辑,是系统的核心。
  4. 基础层:提供数据库、消息中间件等底层服务。

传统的四层架构存在一个问题:基础层通常是其他层的依赖,导致架构不够灵活。随着业务的扩展,这种依赖关系会导致层与层之间的耦合度过高,系统变得难以维护和扩展。

1.3 依赖倒置和五层架构

为了优化四层架构的缺陷,DDD引入了依赖倒置(Dependency Inversion Principle,DIP)。通过这一原则,应用层和领域层可以独立于基础层进行设计和实现,从而实现各层之间的解耦

随着DDD分层架构的演进,五层架构(DCI架构)应运而生。在这一架构中,新增了上下文层(Context Layer),进一步清晰了各层之间的交互关系。


2. DDD分层架构的核心层次

DDD分层架构最常见的形式包括四个核心层次:用户接口层、应用层、领域层和基础层。每个层次都有其特定的职责,确保了系统的高内聚与低耦合。

在这里插入图片描述

2.1 用户接口层(User Interface Layer)

用户接口层的职责是与外部世界进行交互,获取用户的输入并展示系统的输出。这里的“用户”不仅仅指人类用户,还包括程序、自动化测试脚本、批处理任务等。

职责

  • 接收用户输入或请求。
  • 向用户展示结果。
  • 可以通过API暴露给外部系统,支持微服务之间的通信。

用户接口层的关键在于它不处理复杂的业务逻辑,而是负责业务逻辑的展示和用户交互的管理。所有的用户交互都通过用户接口层进行,从而保证了业务逻辑层与外部交互的分离。


2.2 应用层(Application Layer)

应用层是DDD分层架构中最薄的一层,它不直接包含业务逻辑,而是充当业务逻辑的协调者。应用层的主要职责是处理业务流程和用例,调用领域层来执行具体的业务逻辑。

职责

  • 定义应用的业务用例。
  • 协调多个聚合或领域对象的协作。
  • 调用领域层的服务,执行特定的业务操作。
  • 处理跨服务的调用,管理微服务之间的业务流。

应用层的设计非常重要,错误的设计会导致业务逻辑的“外泄”,使得应用层承担过多的职责。应用层不应包含领域模型的复杂业务逻辑,而应专注于用例的组合与协调。


2.3 领域层(Domain Layer)

领域层是DDD架构的核心层,负责实现系统的核心业务逻辑。领域层的设计基于领域模型,它由一系列领域对象构成,包含实体、值对象、聚合、领域服务等。领域层的关键在于充血模型,它强调将业务逻辑封装到实体和领域服务中,而不是将业务逻辑拆散到其他层次。

职责

  • 包含领域模型、业务规则和核心业务逻辑。
  • 定义聚合根、实体、值对象和领域服务。
  • 确保系统的业务逻辑与领域概念紧密关联。

领域层的设计应该尽可能反映真实世界的业务需求,领域服务负责在业务逻辑复杂时,协调多个聚合或领域对象来实现业务操作。


2.4 基础层(Infrastructure Layer)

基础层为系统提供通用的技术服务,如数据库访问、缓存、消息中间件等。基础层的设计采用依赖倒置原则,确保它不与领域层或应用层紧密耦合。

职责

  • 提供底层服务,如持久化、消息队列、缓存等。
  • 封装与外部系统的交互,如数据库、第三方API等。
  • 实现仓储模式(Repository),将数据访问的实现与业务逻辑解耦。

基础层的设计需要关注如何确保底层技术服务与业务层的独立性,以便后期可以方便地替换或优化底层实现。


3. DDD分层架构的重要原则

DDD分层架构遵循一系列的设计原则,确保系统的灵活性和可维护性。最重要的原则之一是“每层只能与其下方的层发生耦合”。这一原则的实施确保了不同层之间的责任清晰,降低了系统的复杂性。

3.1 严格分层架构 vs 松散分层架构

DDD分层架构可以分为两种:严格分层架构和松散分层架构。

  • 严格分层架构:每层只能依赖于其下方的直接层。例如,应用层只能调用领域层,领域层只能调用基础层。这样的设计确保了服务之间的依赖关系清晰,易于管理。

  • 松散分层架构:某些层可以与其下方的任意层产生依赖,依赖关系较为复杂,适用于更灵活的设计需求。

对于大多数项目而言,采用严格分层架构可以带来更高的可管理性和维护性。尤其是在微服务架构中,严格分层架构有助于保持服务的清晰边界,避免服务间的相互干扰。


3.2 依赖倒置原则(DIP)

依赖倒置是DDD架构中的核心设计原则。它要求高层模块(如应用层、领域层)不应依赖于低层模块(如基础层),而是通过接口或抽象层来进行解耦。通过这种方式,系统可以轻松应对底层技术的变化(如数据库切换、缓存服务更换等),而不需要大规模修改上层逻辑。


4. DDD分层架构的演进

随着业务的变化,领域模型和微服务架构也会经历演进。DDD分层架构为这一演进提供了很好的支持。通过对业务逻辑进行精细化的分层和模块化,我们可以灵活应对业务变化,确保架构的稳定性和扩展性。

4.1 领域模型与微服务架构的演进

领域模型不是一成不变的,随着业务需求的变化,领域模型也会经历不断的调整和重构。在DDD分层架构中,应用层负责协调各个微服务之间的业务操作,因此微服务的演进往往伴随着领域模型的调整。

微服务架构的演进

领域模型中对象的层次从内到外依次是:值对象、实体、聚合和限界上下文.

实体或值对象的简单变更,一般不会让领域模型和微服务发生大的变化。但聚合的重组或拆分却可以。这是因为聚合内业务功能内聚,能独立完成特定的业务逻辑。那聚合的重组或拆分,势必就会引起业务模块和系统功能的变化了。

这里我们可以以聚合为基础单元,完成领域模型和微服务架构的演进。聚合可以作为一个整体,在不同的领域模型之间重组或者拆分,或者直接将一个聚合独立为微服务。
在这里插入图片描述

结合上图,以微服务 1 为例,讲解下微服务架构的演进过程:

  • 当发现微服务 1 中聚合 a 的功能经常被高频访问,以致拖累整个微服务 1 的性能时,我们可以把聚合 a 的代码,从微服务 1 中剥离出来,独立为微服务 2。这样微服务 2 就可轻松应对高性能场景。

  • 在业务发展到一定程度以后,你会发现微服务 2 的领域模型有了变化,聚合 d 会更适合放到微服务 1 的领域模型中。这时你就可以将聚合 d 的代码整体搬迁到微服务 1 中。如果你在设计时已经定义好了聚合之间的代码边界,这个过程不会太复杂,也不会花太多时间。

  • 最后我们发现,在经历模型和架构演进后,微服务 1 已经从最初包含聚合 a、b、c,演进为包含聚合 b、c、d 的新领域模型和微服务了。


微服务内服务的演进

在微服务内部,实体的方法被领域服务组合和封装,领域服务又被应用服务组合和封装

在这里插入图片描述

在服务设计时,你并不一定能完整预测有哪些下层服务会被多少个上层服务组装,因此领域层通常只提供一些原子服务,比如领域服务 a、b、c。但随着系统功能增强和外部接入越来越多,应用服务会不断丰富。有一天你会发现领域服务 b 和 c 同时多次被多个应用服务调用了,执行顺序也基本一致。这时你可以考虑将 b 和 c 合并,再将应用服务中 b、c 的功能下沉到领域层,演进为新的领域服务(b+c)。这样既减少了服务的数量,也减轻了上层服务组合和编排的复杂度.


4.2 从三层架构到DDD分层架构的转型

传统的三层架构通常将业务逻辑和数据访问逻辑混合在一起,而DDD分层架构通过分离领域层、应用层和基础层,清晰地定义了各层的职责。这一转型过程通常需要以下几个步骤:

  1. 明确领域模型:首先需要深入理解业务需求,设计出符合业务场景的领域模型。
  2. 拆分业务逻辑:将复杂的业务逻辑拆分到领域层中,避免让应用层承担过多的业务处理。
  3. 重构基础层:基础层不应直接依赖于业务层,而是通过接口与领域层和应用层进行交互。

在这里插入图片描述
三层架构向 DDD 分层架构演进,主要发生在业务逻辑层和数据访问层.

  • DDD 分层架构在用户接口层引入了 DTO,给前端提供了更多的可使用数据和更高的展示灵活性。DDD 分层架构对三层架构的业务逻辑层进行了更清晰的划分,改善了三层架构核心业务逻辑混乱,代码改动相互影响大的情况。DDD 分层架构将业务逻辑层的服务拆分到了应用层和领域层。应用层快速响应前端的变化,领域层实现领域模型的能力

  • 另外一个重要的变化发生在数据访问层和基础层之间。三层架构数据访问采用 DAO 方式;DDD 分层架构的数据库等基础资源访问,采用了仓储(Repository)设计模式,通过依赖倒置实现各层对基础资源的解耦。仓储又分为两部分:仓储接口和仓储实现。仓储接口放在领域层中,仓储实现放在基础层。原来三层架构通用的第三方工具包、驱动、Common、Utility、Config 等通用的公共的资源类统一放到了基础层


5. 小结

DDD分层架构为微服务架构的设计提供了强有力的支持。它通过将复杂的业务逻辑分层管理,使得系统更加模块化、灵活,并且能够随着业务需求的变化进行调整。在实际应用中,通过严格分层和依赖倒置,DDD架构能够有效降低各层之间的耦合,提高系统的可维护性和扩展性。

随着微服务架构和业务需求的不断变化,DDD分层架构也会不断演进,成为更加灵活、可扩展的解决方案。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2289570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

主流的AEB标准有哪些?

目录 1、AEB的技术构成与工作原理 2、典型应用场景举例 3、AEB的功能分类 4、AEB系统性能评估的关键因素 5、全球AEB技术标准概览 5.1、联合国欧洲经济委员会(UN ECE) 5.2、美国NHTSA法规 5.3、中国标准 5.4、印度AIS 185 5.5、澳大利亚ADR法规…

开源智慧园区管理系统如何重塑企业管理模式与运营效率

内容概要 在如今快速发展的商业环境中,企业面临着日益复杂的管理挑战。开源智慧园区管理系统应运而生,旨在通过技术创新来应对这些挑战。它不仅是一个简单的软件工具,而是一个全面整合大数据、物联网和智能化功能的综合平台,为企…

decison tree 决策树

熵 信息增益 信息增益描述的是在分叉过程中获得的熵减,信息增益即熵减。 熵减可以用来决定什么时候停止分叉,当熵减很小的时候你只是在不必要的增加树的深度,并且冒着过拟合的风险 决策树训练(构建)过程 离散值特征处理:One-Hot…

【AI论文】VideoAuteur:迈向长叙事视频

摘要:近期的视频生成模型在制作持续数秒的高质量视频片段方面已展现出令人鼓舞的成果。然而,这些模型在生成能传达清晰且富有信息量的长序列时面临挑战,限制了它们支持连贯叙事的能力。在本文中,我们提出了一个大规模烹饪视频数据…

循环神经网络(RNN)+pytorch实现情感分析

目录 一、背景引入 二、网络介绍 2.1 输入层 2.2 循环层 2.3 输出层 2.4 举例 2.5 深层网络 三、网络的训练 3.1 训练过程举例 1)输出层 2)循环层 3.2 BPTT 算法 1)输出层 2)循环层 3)算法流程 四、循…

Linux网络 | 网络层IP报文解析、认识网段划分与IP地址

前言:本节内容为网络层。 主要讲解IP协议报文字段以及分离有效载荷。 另外, 本节也会带领友友认识一下IP地址的划分。 那么现在废话不多说, 开始我们的学习吧!! ps:本节正式进入网络层喽, 友友们…

2025年大年初一篇,C#调用GPU并行计算推荐

C#调用GPU库的主要目的是利用GPU的并行计算能力,加速计算密集型任务,提高程序性能,支持大规模数据处理,优化资源利用,满足特定应用场景的需求,并提升用户体验。在需要处理大量并行数据或进行复杂计算的场景…

python算法和数据结构刷题[2]:链表、队列、栈

链表 链表的节点定义: class Node():def __init__(self,item,nextNone):self.itemitemself.nextNone 删除节点: 删除节点前的节点的next指针指向删除节点的后一个节点 添加节点: 单链表 class Node():"""单链表的结点&quo…

Baklib解析内容中台与人工智能技术带来的价值与机遇

内容概要 在数字化转型的浪潮中,内容中台与人工智能技术的结合为企业提供了前所未有的发展机遇。内容中台作为一种新的内容管理和生产模式,通过统一管理和协调各种内容资源,帮助企业更高效地整合内外部数据。而人工智能技术则以其强大的数据…

Flask框架基础入门教程_ezflaskapp

pip install flaskFlask 快速入门小应用 学东西,得先知道我们用这个东西,能做出来一个什么东西。 一个最小的基于flask 的应用可能看上去像下面这个样子: from flask import Flask app Flask(__name__)app.route(/) def hello_world():ret…

黑马点评 - 商铺类型缓存练习题(Redis List实现)

首先明确返回值是一个 List<ShopType> 类型那么我们修改此函数并在 TypeService 中声明 queryTypeList 方法&#xff0c;并在其实现类中实现此方法 GetMapping("list")public Result queryTypeList() {return typeService.queryTypeList();}实现此方法首先需要…

洛谷P4057 [Code+#1] 晨跑

题目链接&#xff1a;P4057 [Code#1] 晨跑 - 洛谷 | 计算机科学教育新生态 题目难度&#xff1a;普及一 题目分析&#xff1a;这道题很明显是求最大公倍数&#xff0c;写题解是为了帮助自己复习。 下面用两种方法介绍如何求最大公倍数&#xff1a; 暴力破解 #include<bits…

讯飞绘镜(ai生成视频)技术浅析(四):图像生成

1. 技术架构概述 讯飞绘镜的图像生成技术可以分为以下几个核心模块: 文本理解与视觉元素提取:解析脚本中的场景描述,提取关键视觉元素(如人物、场景、物体等)。 视觉元素生成:根据文本描述生成具体的视觉元素(如人物、场景、物体等)。 分镜画面生成:将视觉元素组合成…

FreeRTOS从入门到精通 第十五章(事件标志组)

参考教程&#xff1a;【正点原子】手把手教你学FreeRTOS实时系统_哔哩哔哩_bilibili 一、事件标志组简介 1、概述 &#xff08;1&#xff09;事件标志位是一个“位”&#xff0c;用来表示事件是否发生。 &#xff08;2&#xff09;事件标志组是一组事件标志位的集合&#x…

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…

deepseek大模型本机部署

2024年1月20日晚&#xff0c;中国DeepSeek发布了最新推理模型DeepSeek-R1&#xff0c;引发广泛关注。这款模型不仅在性能上与OpenAI的GPT-4相媲美&#xff0c;更以开源和创新训练方法&#xff0c;为AI发展带来了新的可能性。 本文讲解如何在本地部署deepseek r1模型。deepseek官…

常见“栈“相关题目

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 1047.删除字符串中的所有相邻重复项 844.比较含退格的字符串 227.基本计算器 II 394.字符串解码 946.验证栈序列 104…

QT实现有限元软件操作界面

本系列文章致力于实现“手搓有限元&#xff0c;干翻Ansys的目标”&#xff0c;基本框架为前端显示使用QT实现交互&#xff0c;后端计算采用Visual Studio C。 本篇将二维矩形截面梁单元&#xff08;Rect_Beam2D2Node&#xff09;组成的钢结构桥作为案例来展示软件功能。 也可以…

软件工程经济学-日常作业+大作业

目录 一、作业1 作业内容 解答 二、作业2 作业内容 解答 三、作业3 作业内容 解答 四、大作业 作业内容 解答 1.建立层次结构模型 (1)目标层 (2)准则层 (3)方案层 2.构造判断矩阵 (1)准则层判断矩阵 (2)方案层判断矩阵 3.层次单排序及其一致性检验 代码 …

Go学习:Go语言中if、switch、for语句与其他编程语言中相应语句的格式区别

Go语言中的流程控制语句逻辑结构与其他编程语言类似&#xff0c;格式有些不同。Go语言的流程控制中&#xff0c;包括if、switch、for、range、goto等语句&#xff0c;没有while循环。 目录 1. if 语句 2. switch语句 3. for语句 4. range语句 5. goto语句&#xff08;不常用…