领域驱动架构(DDD)建模

news2025/1/13 10:29:20

一、背景

常见的软件开发方式是拿到产品需求后,直接考虑数据库中表应该如何设计,这种方式已经将设计与业务需求脱节,而更多的是直接考虑应该如何实现了,这有点本末倒置。而DDD是从领域(问题域)为出发点进行的设计方法。

领域驱动设计的核心是“领域”,从一开始就要让团队走到正确的点上。当我们组建好了团队之后,应该从哪里开始?不是UI原型设计,不是架构设计,不是设计数据库,这些事情重要却非最高优先级。用正确的方法做正确的事情,运用领域驱动设计,就是要先识别问题域,进而为团队提炼达成共识的领域知识。要做到这一点,离不开团队各个角色的沟通与协作。

二、DDD 要解决的两个核心问题:
​1. 业务架构
如何合理的设计?
2. 如何使系统架构域业务架构保持一致并具备可持续的扩展?
领域驱动的设计目标:有效建模,并运⽤用领域模型驱动团队进⾏行行沟通分析、设计及开发。

 

三、领域驱设计的核心思想

1、模型与现实业务的统一
・模型和程序设计的核心相互影响。正是模型与实现之间的紧密联系才使模型变得有⽤, 并确保我们在模型中所进行的分析能够转化为最终程序。
・模型与实现之间的这种紧密结合 在维护和后续开发期间也会很有用,因为我们可以基于对模型的理理解来解释代码。
2、统一(业务和技术)语言
・模型是团队所有成员使用的通⽤语⾔的中枢。由于模型与实现之间的关联,开发人员可 以⽤该语⾔来讨论程序。
・他们可以在无需翻译的情况下与领域专家进行沟通。⽽且由于该语言是基于模型的,因此我们可借助自然语⾔对模型本身进行精化。
3、团队的持续学习,消化知识,系统持续的发展
模型是浓缩的知识。模型是团队一致认同的领域知识的组织⽅式
和重要元素的区分⽅ 式。透过我们如何选择术语、分解概念以及将概念联系起来,模型纪录了我们看待领域的⽅式。
当开发⼈员和领域专家在将信息组织为模型时,这一共同的语⾔ (模型) 能够促使 他们⾼效地协作。

四、DDD设计步骤

4.1 基本概念

(1)实体(Entity):一个由它的标识定义的对象叫做实体。通常实体具备唯一ID,能够被持久化,具有业务逻辑,对应现实世界业务对象。

(2)值对象(Value Object):一个没有概念上标识符描述一个领域方面的对象,这些对象是用来表示临时的事物,或者可以认为值对象是实体的属性,这些属性没有特性标识但同时表达了领域中某类含义的概念。通常值对象不具有唯一ID,由对象的属性描述,可以用来传递参数或对实体进行补充描述。

(3)服务(Service):提供的操作是它提供给使用它的客户端,并突出领域对象的关系。所有的Service只负责协调并委派业务逻辑给领域对象进行处理,其本身并真正实现业务逻辑,绝大部分的业务逻辑都由领域对象承载和实现了。Service可与多种组件进行交互,当一个领域操作被视为一个重要的领域概念,一般就作为领域服务,服务是无状态的。

(4)聚合(Aggregate):用来定义领域对象所有权和边界的领域模式,是用来帮助简化模型对象间的关系。通过定义对象之间清晰的所属关系和边界来实现领域模型的内聚,并避免了错综复杂的难以维护的对象关系网的形成。

(5)聚合根(Aggregate Root):每个聚合都有一个根对象(聚合根实体),从外部访问只能通过这个对象。根实体对象有组成聚合所有对象的引用,但是外部对象只能引用根对象实体。只有聚合根才能使用仓储库直接查询,如果根实体被删除,聚合内部的其它对象也将被删除。

(6)仓储(Repository):是用来管理实体的集合,仓储里面存放的对象一定是聚合,原因是domain是以聚合的概念来划分边界的;聚合作为一个整体概念,要么一起被取出来,要么一起被删除。外部访问不会单独对某个聚合内的子对象进行单独操作。因此,我们只对聚合设计仓储。

(7)工厂(Factory):用来封装创建一个复杂对象,尤其是聚合时所需的知识,是将创建对象的细节隐藏起来。如客户传递给工厂一些简单的参数,然后工厂可以在内部创建一个复杂的领域对象,然后返回给客户。

(8)领域事件(Domain Event):是将领域对象从对repository或service的依赖中解脱出来,避免让领域对象对这些设施产生直接依赖。领域事件的触发点在领域模型(domain model)中。就是当领域对象的业务方法需要依赖到这些对象时就发出一个事件,这个事件会被相应的对象监听到并做出处理。

4.2 描述需求

需求描述要点:

(1)在对业务充分沟通和深入理解的基础上,从业务描述中提取名词,作为关键字;

(2)对关键需求点描述的格式应尽量表述为“用户+需求场景+操作对象”,并在团队之间达成共识;

(3)从提取出来的名词中总结实体,形成问题域;

(4)需求描述格式不限,可以用UML提供的方法和图例进行领域模型设计、确定模型之间的关系,也可以用其他传统方式,目标是团队成员理解一致即可。

用UML方法描述需求举例:

4.3、划分领域

(1)领域(Domain):领域就是问题域,一个领域可以拆分为多个子领域(Sub Domain)。

(2)核心子域(Core Domain):子领域中最核心的叫核心子域,团队的核心资源应该用在核心子域上,因为它是产品成败的关键。

(3)支撑子域(Supporting Subdomain):除了Core Domain外,其他的是支撑子域。

(4)通用子域(Generic Subdomain):有些支撑子域比较特殊,因为它解决的是一类通用问题,这类子域我们叫做通用子域。

  通用子域对应的限界上下文,通常会跨多个子域;多个子领域有时会有相交的部分,称作共享内核,体现到代码上就是同一份代码,在多个领域模型中复用,领域示意图如下:

4.4、限界上下文

限界上下文划分依据:

(1)围绕语言定义边界:利用语义相关性和功能相关性对用例归类;

(2)与业务能力保持一致:避免限界上下文工作边界过大;

(3)围绕团队创建上下文:从技术角度考虑重用和变化的应对、遗留系统的集成。

美团抽奖平台上下文映射如下:

4.5、战术建模

(1)实体(Entity):当一个对象由其标识(而不是属性)区分时,这种对象称为实体;

(2)值对象(Value Object):当一个对象用于对事务进行描述而没有唯一标识时,它被称作值对象;

(3)聚合根(Aggregate Root):聚合是一组相关对象的集合,作为一个整体被外界访问,聚合根是这个聚合的根节点;

(4)领域事件:领域事件是对领域内发生的活动进行的建模。

一个手绘的简易建模,如下:

6、用DDD写需求规格说明书

总结利用领域模型产出需求规格说明书的一般步骤:

(1)需求的理解和描述,抽取提炼关键字;

(2)根据需求划分出初步的领域和限界上下文,以及上下文之间的关系;

(3)进一步分析每个上下文内部,识别出哪些是实体,哪些是值对象;

(4)对实体、值对象进行关联和聚合,划分出聚合范畴和聚合根,进行建模;

(5)将每个业务场景流程化,按照场景流程,使用事件编排,定义好事件上下游关系;

(6)在工程中实践领域模型,并在实践中检验模型的合理性,倒推模型中不足的地方并重构。

参考:

领域驱动架构(DDD)建模中的模型到底是什么? - 知乎

一文教会你领域建模-CSDN博客

DDD-领域驱动设计 - 知乎

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

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

相关文章

C++面试宝典第1题:爬楼梯

题目 小乐爬楼梯,一次只能上1级或者2级台阶。楼梯一共有n级台阶,请问总共有多少种方法可以爬上楼? 解析 这道题虽然是一道编程题,但实际上更是一道数学题,着重考察应聘者的逻辑思维能力和分析解决问题的能力。 当楼梯只…

严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现)

2.19已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效的算法, 删除表中所有值大于 mink 且小于 maxk 的元素(若表中存在这样的元素)同时释放被删结点空间, 并分析你的算法的时间复杂度(注意:mink 和 maxk 是给定的个参变量,它们的值可以和表中…

QNX时钟调研

SYSPAGE_ENTRY()的使用&#xff0c;SYSPAGE_ENTRY 测试QNX下printf(“poo\n”);的耗时 #include <sys/neutrino.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <sys/syspage.h>int main( void ) {uint64_t cps, …

P7 链表 链表头前方插入新节点

目录 前言 01 链表头插入数据 示例代码 02 指定节点前方插入新节点 测试代码 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C》✨✨✨ &#x1f525; 推荐专栏2: 《 Linux C应用编程&#xff08;概念类&#xff09;_ChenPi的博客-CSDN博客》✨…

Linux系统配置深度学习环境之cudnn安装

前言 一个针对深度学习应用优化的 GPU 加速库。它提供了高性能、高可靠性的加速算法&#xff0c;旨在加速深度神经网络模型的训练和推理过程。 cuDNN 提供了一系列优化的基本算法和函数&#xff0c;包括卷积、池化、规范化、激活函数等&#xff0c;以及针对深度学习任务的高级功…

【MySQL的DQL查询语句】

MySQL的DQL查询语句-----在Navicat下 将学生表导入Navicat中查询语句查询一整张表查询年龄大于22年龄大于22的女生查找文科的学生查找六班的学生计算学生的总分 &#xff08;group by&#xff09;合并两表 &#xff08;join on xxxx&#xff09;合并两张表 并求总分先合并在聚合…

一站式自动化:Ansible Playbook的全面学习之旅

1 Playbook介绍 1.1 Playbook介绍 playbook 是由一个或多个play组成的列表 Playbook 文件使用YAML来写的 1.2 YAML 1.2.1 介绍 是一种表达资料序列的格式&#xff0c;类似XML Yet Another Markup Language 2001年首次发表 www.yaml.org 1.2.2 特点 可读性好 和脚本语言交…

机器学习笔记 - 什么是模型量化压缩技术?

一、简述 我们都知道现实世界是连续的状态,而计算机世界是离散的状态,这是什么意思呢?我们看一下下图,最右边的马力欧(高清)的状态,可以想象现实世界是连续的状态,而电脑世界在图像上呈现的是一格一格子的状态(左图)是离散的状态。 所以在计算机世界如果想要…

医疗器械设备模组的具体应用

直线模组是一种高精度、高速度的精密传动元件&#xff0c;目前被广泛应用在各种工业自动化领域&#xff1b;尤其是在激光加工、电子制造、医疗设备、物流设备和机器人等行业中&#xff0c;都发挥着重要作用&#xff0c;接下来我们看看医疗器械设备模组的具体应用吧&#xff01;…

智慧灯杆系统平台架构设计需要考虑的几个要点

智慧灯杆是一种集成了各种先进技术的道路照明设施。它不仅提供照明服务&#xff0c;还可以具有物联网技术、视频监控、环境监测、广播通讯、无线网络覆盖等多种功能。这些智能功能可以通过互联网进行控制和管理&#xff0c;从而实现智慧城市的建设。智慧灯杆能够提升城市的智能…

Webgis学习总结

前言&#xff1a; 作者跟随视频学习了webgis内容进行如下学习复习总结 参考&#xff1a;新中地学习笔记 WebGIS第一课&#xff1a;测试高德API并通过&#xff1a; 注册申请高德API成为开发者&#xff0c;创建自己的项目和key进行项目初始化&#xff0c;可以使用JS API官方文…

PyQt6 QComboBox下拉组合框控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计34条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

算法基础--双指针

前面已经写了两篇关于算法方面的文章&#xff0c;这几天想了下&#xff0c;决定把这个算法整理成一个系列&#xff0c;除了是帮助自己巩固算法知识外&#xff0c;还能够把自己总结的每种算法的套路保存下来并分享给大家&#xff0c;这样以后即使是哪天想要重拾起来&#xff0c;…

Apache Doris 详细教程(三)

7、监控和报警 Doris 可以使用 Prometheus 和 Grafana 进行监控和采集&#xff0c;官网下载最新版即可。 Prometheus 官网下载&#xff1a;https://prometheus.io/download/ Grafana 官网下载&#xff1a;https://grafana.com/grafana/download Doris 的监控数据通过 FE 和…

排序算法介绍(四)快速排序

0. 简介 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;采用了分治的思想。它选择一个基准元素&#xff0c;通过一趟排序将待排序序列分割成独立的两部分&#xff0c;其中一部分的所有元素都比基准元素小&#xff0c;另一部分的所有元素都比基准…

C++-类和对象

目录 一.C语言和C的区别 二.类的引入 三.类的定义 1.类的定义 2.类的成员方法的两种定义方式&#xff1a; 3.类的成员变量的定义 四.类的访问限定符及封装 1.访问限定符 五.面向对象的三大特征 1.面向对象的三大特征分别是什么 2.封装 六.类的作用域 七.创建类对象 1.类…

【csdn默认使用操作详解】

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

国际语音通知系统有哪些优点?国际语音通知系统有哪些应用场景?

国际语音通知是一种全球性的通信工具&#xff0c;它通过语音方式向用户发送各种重要信息和提示。无论是快递到货的取件提醒、机场航班的延误通知&#xff0c;还是银行账户的余额提醒&#xff0c;国际语音通知都能准确、迅速地将信息传达给用户。 三、国际语音通知系统有哪些优…

qnx修改tcp和udp缓冲区默认大小

拷贝/home/test/qnx/qos223/target/qnx7/aarch64le/sbin/sysctl进系统中 https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.utilities/topic/s/sysctl.html kern.sbmax 默认262144&#xff0c;这个限制住了发送、接收缓冲器大小 ./sysctl -w kern.sbmax10000…

51单片机应用从零开始(十)·指针

指针 C语言指针是一种保存变量地址的数据类型。它可以让程序直接访问内存中的数据&#xff0c;而不需要通过变量名来访问。指针变量存储的是一个地址&#xff0c;这个地址指向内存中的某个位置&#xff0c;该位置存储了一个值。 在C语言中&#xff0c;可以使用&运算符取得一…