初识DDD

news2024/11/26 15:26:57

DDD领域驱动设计

1 DDD是什么?

领域驱动设计(Domain-Driven Design, DDD)是一种软件设计方法论,旨在处理复杂的业务需求和系统设计。由Eric Evans在他的同名书中提出,DDD关注将业务需求和软件架构紧密结合,通过领域模型和相应的设计模式,创建灵活且可维护的系统。

1.1 领域驱动设计的优势
  • 解决复杂性:通过将复杂的业务需求分解成更小的子域和限界上下文,DDD帮助开发人员更好地理解和管理复杂性。
  • 业务与技术的统一:通过领域模型和共同的语言,业务人员和技术团队可以更高效地沟通和协作。
  • 灵活性和可维护性:DDD设计的系统具有更高的灵活性和可维护性,能够更好地适应业务变化。
1.2 领域驱动设计的应用场景

DDD非常适用于具有高度复杂性和业务逻辑的系统,如电商平台、金融系统、物流管理等。但并非所有项目都适合使用DDD,对于一些简单的系统,可能不需要这么复杂的设计方法。

领域驱动设计通过清晰的领域划分和模型设计,应对复杂的软件系统,确保系统的稳定性、扩展性和灵活性。

2 领域驱动设计(DDD)概念

领域驱动设计(Domain-Driven Design, DDD)是一种为了解决复杂软件设计而提出的优秀方案,但并非唯一的方法。

2.1 核心概念
  • 领域: 领域是指所有业务规则、定义、范围、知识等的抽象概念。比如,用户支付业务属于交易域,平台提供售后服务属于服务域(或客服域),其他如金融域、人效域、物流域等。
  • 分而治之: 通过把复杂的领域(问题)分解成更小的子域,每个子域都有明确的边界和核心实体。通过一系列的拆分、归类、衍生,找到最优解。
2.2 应对复杂性的策略
  1. 保持内核稳定性和扩展性: 在多变的业务环境中,通过稳定的内核设计,确保系统的扩展性和灵活性。
  2. 领域模型的共识性: 领域模型贯穿了从设计到交付的软件生命周期,开发、产品、架构师围绕统一的模型进行设计和讨论,确保一致性。
2.3 领域模型的特点
  • 图形表达方式: 除了实体模型图的表达比较特殊,其他如时序图、状态机、流程图等表达方式与其他方法并无不同。
  • 业务的抽象: 领域模型是对业务的抽象,基于现实但不等于现实。

3 DDD和MVC的比较

在DDD理念提出来之前,最经典的开发模式就是MVC了。

3.1 MVC组成部分

**1.Model(模型)**
  • 职责:处理业务逻辑和数据。模型负责与数据库交互,进行数据的CRUD(创建、读取、更新、删除)

  • 实现:在图中,Model使用JavaBean来封装数据和业务逻辑。JavaBean类通常包含属性、getter和setter方法,以及一些业务逻辑方法。

    2.View(视图)

  • 职责:负责展示数据给用户。视图从模型获取数据,并将其以用户友好的方式展示出来。

  • 实现:在图中,View使用JSP(JavaServer Pages)来显示前端页面。JSP文件包含HTML代码,并且可以嵌入Java代码来动态显示数据。

    3.Controller(控制器)

  • 职责:作为模型和视图之间的中介,处理用户输入,调用模型来处理数据,并将结果交给视图进行展示。

  • 实现:在图中,Controller使用Servlet来实现。Servlet接收客户端的请求,调用相应的JavaBean处理业务逻辑,然后将数据转发给JSP页面进行展示。

3.2 MVC工作流程

  1. 用户请求
  • 用户通过浏览器发送请求到服务器。
  1. Controller接收请求
  • Servlet作为Controller,接收客户端的请求。

  • Controller获取用户输入,调用相应的模型进行处理。

  1. 调用模型(Model)
  • Controller调用JavaBean(模型)进行业务逻辑处理,例如查询数据库。

  • JavaBean执行数据操作,并返回处理结果。

  1. 将数据传递给视图(View)
  • Controller将处理结果(数据)传递给JSP页面(视图)。

  • JSP页面接受数据并进行展示。

  1. 显示数据
  • 浏览器接收服务器返回的HTMl页面,并将结果显示给用户。

3.3 MVC架构存在的问题

  1. 控制器过于臃肿
  • 包含大量业务逻辑,导致难以维护。
  1. 模型职责不明确
  • 业务逻辑、数据访问混杂,模型变得复杂。
  1. 视图层逻辑复杂化
  • 需要大量数据处理和格式化操作,代码难以维护。
  1. 模块间耦合度高
  • 各层之间调用关系复杂,难以单独测试和调试。
  1. 难以应对复杂业务场景
  • 频繁修改代码,系统难以适应新需求。
  1. 数据一致性问题
  • 难以保证数据一致性,可能导致数据错误。
  1. 缺乏领域层的抽象
  • 业务逻辑分散,维护复杂业务规则困难。

MVC架构适用于简单业务场景,但在面对复杂、多变的业务需求时,容易出现控制器和模型臃肿、模块耦合度高、数据一致性难保证等问题,导致系统难以维护和扩展。

4 DDD可以带来的价值

4.1 团队价值

  • 统一语言

  • 清晰的边界定义

  • 领域能力沉淀和复用

  • 面向业务建模

  • 设计和代码的等价

4.2 个人价值

  • 提升全局视野

  • 提升业务sense

  • 构建体系化思维

5 领域驱动设计的核心概念

5.1 DDD完整设计流程

  1. 提炼业务流程

在这个阶段,目标是对业务进行深入理解和分析,以便为后续的设计奠定基础。这包括:

  • 角色:确定在业务流程中涉及的不同角色。
  • 业务事件:识别关键的业务事件,这些事件通常是引发系统行为的触发器。
  • 参与者:确定业务流程中所有参与者,他们可能是用户、系统或其他外部实体。
  • 流程:梳理业务流程,明确各个步骤和环节。
  • 描述:对上述元素进行详细描述,确保每个元素都得到充分理解。
  1. 战略设计

这一阶段主要是从宏观角度对业务进行架构设计,定义系统的高层次结构和边界。具体包括:

  • 领域:划分业务领域,定义系统的核心业务领域。
  • 子域:将领域进一步细分为子域,每个子域对应一个相对独立的业务模块。
  • 通用域:识别通用领域,这些领域包含在多个子域中共享的业务逻辑。
  • 支撑域:确定支撑域,这些领域为核心业务领域提供辅助功能。
  • 限界上下文:定义每个子域的边界和上下文,明确子域之间的接口和交互方式。
  1. 战术设计

在战术设计阶段,重点是具体的技术实现和细节设计,主要包括:

  • 实体:定义业务中的实体,它们通常是具有唯一标识和生命周期的对象。
  • 值对象:定义值对象,这些对象没有唯一标识,通常用于描述某些属性或值。
  • 聚合:将相关的实体和值对象组合成聚合,通过聚合根来管理。
  • 聚合根:确定每个聚合的根实体,聚合根负责聚合内部的一致性。
  • 资源库:定义资源库,用于管理实体的持久化和检索。
  • 工厂:使用工厂模式来创建复杂的对象,简化对象的创建过程。
  • 领域服务:定义领域服务,这些服务包含跨多个实体和值对象的业务逻辑。
  • 领域事件:定义领域事件,捕捉和传递领域内的重要事件。
  1. 编码

最后一步是根据战术设计进行编码实现:

  • 代码分层:根据战术设计将代码进行分层,实现清晰的代码结构。
  • 依赖注入:使用依赖注入和其他设计模式,确保系统的模块化和可测试性。
  • 单元测试:编写单元测试,确保每个模块和组件的功能正确。

5.2 核心概念

  1. 领域(Domain)
  • 领域是指特定业务范围内的知识、逻辑和规则的集合。它包括所有与业务相关的定义和概念。
  1. 子域(Subdomain)
  • 将大的领域划分成更小的子域,每个子域代表一个特定的业务问题或功能。通过分解,复杂的问题变得更易于管理。
  1. 限界上下文(Bounded Context)
  • 定义领域模型的边界。在每个限界上下文内,特定的术语和规则有明确的含义,不同的限界上下文可能有不同的模型和规则。
  1. 领域模型(Domain Model)
  • 领域模型是对业务领域的抽象和表示,包括实体(Entities)、值对象(Value Objects)、聚合(Aggregates)、领域事件(Domain Events)等元素。领域模型是开发、产品、架构师等各方达成共识的核心。
  1. 聚合(Aggregate)
  • 聚合是具有一致性的聚合根及其相关对象的集合。聚合根负责聚合的状态一致性,并确保业务规则的执行。
  1. 实体(Entity)
  • 实体具有唯一标识和可变状态,是业务操作的核心对象。
  1. 值对象(Value Object)
  • 值对象没有唯一标识,通常是不可变的,代表特定的业务值。
  1. 领域服务(Domain Service)
  • 领域服务封装了跨实体或值对象的业务逻辑,提供特定领域的操作和功能。

6 领域建模

领域建模是DDD最关键的部分,它的目的归纳起来就是:提炼业务知识,形成统一语言,沉淀领域模型。

领域建模是领域驱动设计(DDD)的核心步骤,它通过将复杂的业务需求和规则转化为可管理的领域模型,使开发团队能够更好地理解和实现业务逻辑。以下是领域建模的主要步骤:

6.1 了解业务领域

  • 业务调研:与业务专家、用户和相关方进行深入交流,理解业务需求、目标和痛点。
  • 业务流程分析:梳理和分析业务流程,明确业务操作、角色和参与者。

6.2 提炼领域概念

  • 识别实体(Entity):找出具有唯一标识和生命周期的对象。例如,订单、客户等。
  • 识别值对象(Value Object):找出没有唯一标识、用来描述某些属性的对象。例如,地址、货币等。
  • 识别聚合(Aggregate):将相关的实体和值对象组合成聚合,通过聚合根来管理。例如,订单聚合包括订单实体、订单项值对象等。
  • 识别领域服务(Domain Service):找出跨多个实体和值对象的业务逻辑。例如,支付服务、库存检查服务等。

6.3 定义限界上下文(Bounded Context)

  • 划分子域:根据业务领域和业务流程,将系统划分为多个子域,每个子域对应一个相对独立的业务模块。
  • 明确上下文边界:定义每个子域的边界,明确子域之间的接口和交互方式,确保子域内部的一致性。

6.4 设计领域模型

  • 创建实体和值对象:设计实体和值对象的属性和行为,确保它们能够充分表达业务逻辑。
  • 定义聚合根:确定每个聚合的根实体,聚合根负责管理聚合内部的一致性。
  • 设计资源库(Repository):定义资源库接口,用于管理实体的持久化和检索。
  • 实现领域服务:设计领域服务的接口和实现,将复杂的业务逻辑封装在领域服务中。
  • 设计领域事件(Domain Event):定义领域事件,捕捉和传递领域内的重要事件。

6.5 验证和迭代

  • 与业务专家验证:与业务专家持续沟通,验证领域模型是否正确反映了业务需求。
  • 迭代优化:根据反馈不断迭代和优化领域模型,确保其准确性和实用性。

6.6 实现和测试

  • 代码实现:根据领域模型进行代码实现,确保每个模型元素都得到正确实现。
  • 单元测试:编写单元测试,验证领域模型的各个部分是否正确工作。
  • 集成测试:进行集成测试,确保各个子域和组件之间的协作正常。

6.7 总结

领域建模是一个持续迭代的过程,贯穿于项目的整个生命周期。通过领域建模,可以将复杂的业务需求转化为清晰的领域模型,提高系统的可理解性、可维护性和可扩展性。以下是领域建模的主要步骤总结:

  1. 了解业务领域:深入理解业务需求和流程。
  2. 提炼领域概念:识别实体、值对象、聚合、领域服务等。
  3. 定义限界上下文:划分子域,明确上下文边界。
  4. 设计领域模型:创建和设计实体、值对象、聚合根、资源库、领域服务和领域事件。
  5. 验证和迭代:与业务专家验证模型,持续优化。
  6. 实现和测试:代码实现和单元测试,确保模型的正确性。

开源项目推荐

GitHub - lml200701158/ddd-framework: DDD框架

GitHub - Air433/dddbook: spring boot 领域驱动设计Demo

GitHub - EalenXie/spring-microservice-ddd: 微服务+DDD代码结构例子

GitHub - louyanfeng25/ddd-demo: MVC【以mybatis-plus为orm框架】迁移至DDD的demo

GitHub - dddplus/dddplus-demo: ♨️ Demonstrate how to use DDDplus to build a complex OMS.演示如何使用DDDplus实现一套订单履约中台OMS

GitHub - xlorne/springboot-ddd-demo: 如何做好一个项目?springboot与领域模型该如何结合?

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

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

相关文章

算法设计与分析--近似算法作业及答案

近似算法作业题目 1 k-center 近似算法题目描述参考答案解答 题目 2 均衡负载算法题目描述参考答案解答 题目 3 多项式归约题目描述参考答案解答 近似算法–徐小华 近似算法作业 题目 1 k-center 近似算法 题目描述 问题 1:假设给定 n n n 个指定的城市在一个平…

findfont: Generic family ‘sans-serif‘ not found because none of the ...: SimHei

警告过程 python代码在使用matplotlib画图时,如果在title,xlabel,ylabel中出现了中文,则会出现字体警告,中文字符显示为方框 例如代码: # matplotlib画图# 设置色带plt.imshow(data, cmapplt.cm.YlGn) #…

Python基于逻辑回归分类模型、决策树分类模型、随机森林分类模型和XGBoost分类模型实现乳腺癌分类预测项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 在当今医疗健康领域,乳腺癌作为威胁女性健康的主要恶性肿瘤之一,其早期诊断与精…

仓库管理系统16--入库管理

原创不易&#xff0c;打字不易&#xff0c;截图不易&#xff0c;多多点赞&#xff0c;送人玫瑰&#xff0c;留有余香&#xff0c;财务自由明日实现。 1、创建物资入库用户控件 <UserControl x:Class"West.StoreMgr.View.InStoreView"xmlns"http://schema…

市场拓展招聘:完整指南

扩大招聘业务会给你带来很多挑战&#xff0c;更不用说你已经在处理的问题了。助教专业人士每周花近13个小时为一个角色寻找候选人。此外&#xff0c;客户的需求也在不断变化&#xff0c;招聘机构之间的竞争也在加剧。毫无疑问&#xff0c;对增长有战略的方法会有很大的帮助。一…

RocketMq源码解析九:刷盘机制及过期文件删除

一、刷盘机制 刷盘策略在不同时间进行刷写磁盘。RocketMQ的存储是基于JDK NIO的内存映射机制(MappedByteBuffer)的,消息存储首先将消息追加到内存,再根据配置的刷写磁盘 同步刷盘表示消息追加到内存后,立即将数据刷写到文件系统中。代码的调用链如下: submi…

web使用cordova打包Andriod

一.安装Gradel 1.下载地址 Gradle Distributions 2.配置环境 3.测试是否安装成功 在cmd gradle -v 二.创建vite项目 npm init vitelatest npm install vite build 三.创建cordova项目 1.全局安装cordova npm install -g cordova 2. 创建项目 cordova create cordova-app c…

学习过程中遇到的 部分问题及解决办法

1.安装build wheel时报错&#xff1a; The detected CUDA version (12.1) mismatches the version that was used to compile PyTorch (11.7). Please make sure to use the same CUDA versions. 由于cuda版本和 当前虚拟环境中的pytorch-cudatoolkit版本不同&#xff0c; 解…

梦想CAD二次开发

1.mxdraw简介 mxdraw是一个HTML5 Canvas JavaScript框架&#xff0c;它在THREE.js的基础上扩展开发&#xff0c;为用户提供了一套在前端绘图更为方便&#xff0c;快捷&#xff0c;高效率的解决方案&#xff0c;mxdraw的实质为一个前端二维绘图平台。你可以使用mxdraw在画布上绘…

【系统架构设计师】五、计算机网络(概念|通信技术|网络技术)

目录 一、计算机网络概念 二、通信技术 三、网络技术 3.1 局域网(LAN) 3.1.1 局域网拓扑结构 3.1.2 局域网协议 3.2 无线局域网(WLAN) 3.3 广域网(WAN) 3.4 城域网&#xff08;MAN) 3.5 移动通信网 四、组网技术 4.1 OSI七层模型 4.1.1 交换机 4.1.2 路由器 4.2…

idea Error running ‘Application‘

1、Error running ‘Application’ Error running ApplicationError running Application. Command line is too long.Shorten the command line via JAR manifest or via a classpath file and rerun.找到 .idea/libraies/workspace.xml 中的 PropertiesComponent 属性&#…

python数据分析与可视化二

公共部分 # 引入数据分析工具 Pandas import pandas as pd # 引入数据可视化工具 Matplotlib import matplotlib.pyplot as plt # 引入科学计算库numpy import numpy as np from scipy import stats #解决输出时列名对齐问题 pd.set_option(display.unicode.east_asian_wid…

《数据结构与算法基础 by王卓老师》学习笔记——2.2线性表的案例引入

案例一&#xff1a;一元多项式的运算 案例二&#xff1a;稀疏多项式的运算 案例三&#xff1a;图书信息管理系统 总结

慢动作视频怎么制作?5种方法,轻松制作慢动作视频

在短视频风靡的当下&#xff0c;慢动作视频凭借其独特的视觉效果和引人入胜的节奏感&#xff0c;成为了吸引观众眼球的利器。你是否也想知道如何制作这种令人心动的慢动作视频呢&#xff1f;下面教大家5种能够制作出慢动作视频的方法&#xff0c;一起来学习下吧。 方法一&#…

Nginx反向代理实现Vue跨域注意事项

1、通过搜索引擎访问Nginx官网——免费使用——NGINX开源版(免费下载)或者通过以下链接直接访问Nginx下载页面下载对应的版本(下载页面)。以下以1.24.0为例 2、修改nginx的配置文件&#xff0c;在conf文件夹下&#xff0c;文件名为nginx.conf&#xff1b;以下是我修改完的配置…

2024我们该学习大模型吗?

一、引言 在快速变化的科技行业中&#xff0c;人工智能&#xff08;AI&#xff09;大模型已成为研究和应用的热点。随着AI技术的不断进步&#xff0c;特别是在自然语言处理、计算机视觉和机器学习平台等领域&#xff0c;许多专业人士开始将目光投向AI大模型的开发和应用。 二…

MobPush iOS端海外推送最佳实现

推送注册 在AppDelegate里进行SDK初始化&#xff08;也可以在Info.plist文件中进行AppKey&#xff0c;AppSecret的配置&#xff09;并对通知功能进行注册以及设置推送的环境和切换海外服务器等&#xff0c;参考如下步骤代码&#xff1a; <span style"background-colo…

[漏洞复现] MetInfo5.0.4文件包含漏洞

[漏洞复现] MetInfo5.0.4文件包含漏洞 MetInfo5.0.4 漏洞代码审计 漏洞出现在about/index.php中&#xff0c;因为利用了动态地址&#xff0c;所以存在漏洞。 漏洞检查语句&#xff08;&#xff01;192.168.109.100是我的服务器ip&#xff0c;需要换成自己的&#xff09;&…

[BUUCTF从零单排] Web方向 02.Web入门篇之『常见的搜集』解题思路(dirsearch工具详解)

这是作者新开的一个专栏《BUUCTF从零单排》&#xff0c;旨在从零学习CTF知识&#xff0c;方便更多初学者了解各种类型的安全题目&#xff0c;后续分享一定程度会对不同类型的题目进行总结&#xff0c;并结合CTF书籍和真实案例实践&#xff0c;希望对您有所帮助。当然&#xff0…

jupyter安装及使用

引言 之前安装了anaconda&#xff0c;然后conda的环境管理里面就有jupyter&#xff0c;但是我一直没用过。 但是我用过colab&#xff0c;从使用体验上来说&#xff0c;非常相似&#xff0c;这次给服务器装了一个jupyter&#xff0c;然后我本地连接远程的来用&#xff0c;还挺…