小研究 - 领域驱动设计DDD在IT企业内部网站开发中的运用(二)

news2024/9/28 3:30:56

在企业内部网站的建设过程中,网站后端最初采用传统的表模式的开发方式。这种方式极易导致站点的核心业务逻辑和业务规则分布在架构的各个层和对象中,这使得系统业务逻辑的复用性不高。为了解决这个问题,作者在后期的开发过程中引入了领域驱动设计的开发方式,把系统的业务逻辑独立建模、充分地复用,并基于这些模型打造易于扩展的开发框架,提高了整个团队开发业务逻辑的效率,最终网站如期上线,稳定运行至今。

目录

2 开发模式的应用

2.1 初期采用表模式开发模式

2.2 后期采用DDD开发模式来聚焦业务逻辑

3 结束语


2 开发模式的应用

2.1 初期采用表模式开发模式

在最初的开发过程中,作者带领团队采用表模式开发系统,也就是每个业务功能的开发都遵循如下的流程:
1) 根据业务的需求分析得到数据表的字段,把数据库表建好。
2) 通过ORM将数据库中的表映射成代码中的实体对象。
3) 在业务逻辑层根据功能的需要补充业务逻辑和规则,操作实体对象进行数据的读取和持久化。

这种开发方式简单易行,但是随着网站的功能逐渐增多,逻辑越发地复杂,如下问题逐渐显现出来:
1) 通过ORM得到的实体对象都是贫血模型,它们只有数据库映射的属性和字段,并不具有具体的业务行为。
2) 因为没有明确的约束,核心业务逻辑和业务规则非常容易从业务逻辑层扩散到其他层和对象中。有的跑到了帮助类中、有的跑到了存储过程里,这导致了业务逻辑的复用性不高。

为了解决上述问题,作者再次深入研究了上述的软件开发模式并决定引入DDD来开发和管理项目。

2.2 后期采用DDD开发模式来聚焦业务逻辑

使用DDD开发模式来开发和管理项目,作者带领团队实践了如下的过程。

1) DDD战略设计
①将整个应用程序域进行划分,剥离各个子域在该项目中,经过分析,作者共拆分出账号管理、任务管理、积分管理、图书管理等子域。
②对每个子域进行限界上下文的设计在每个限界上下文中,保证任何一个对象模型的语义是确定的、无歧义的。

虽然两个User对象具有相同的名字,但是它们是完整的用户对象在不同上下文中的投影,是两个不同的对象。

在项目实施的过程中,作者选择将子域和限界上下文一一对应,独立部署在每个AppService中。

2) DDD战术设计
DDD战术设计的核心就是把核心业务逻辑集中放到一起,组成领域层。其他层设计为依赖于该层。领域层中包含所有重要的领域模型,包括聚合根、实体、值对象、领域事件、仓储、领域服务等。

①设计聚合根、实体和领域服务在该项目的领域层中,最重要的对象就是聚合根和实体。它们完成了主要的业务逻辑。

使用聚合根还是实体,在实践中一般都可以,但是如果完成一个业务操作,就一个主要的实体就可以了,不需要其他相关实体的配合,那么暴露这个实体给其他层就可以了。

比如Book这个实体,不仅包含了所有图书的所有信息,还包括增加封面、修改作者、增加点评等各种业务行为。

但是如果完成一个业务操作,需要一个主要的实体,配合上其他一些相关的实体才能完成,那么就将主要的实体暴露成聚合根给其他层使用,把相关的其他实体全部隐藏起来,这些相关的实体的操作统统通过聚合根来暴露。

比如Task这个实体,不仅包含了所有Task自身的信息和操作,还包括其包含的子对象TaskItem实体的信息和各种操作,所以 Task 实体就暴露为聚合根,向外提供所有 Task 和TaskItem的相关操作,其他层无法直接操作TaskItem对象以及其方法。如图6所示。

②设计领域事件
该项目中,非常常见的一个需求就是一个实体改变了,需要通知其他的一些实体就行一些对应的变化。这种需求就需要通过事件模式来实现。

在项目中,作者实现了一个EventBus作为通用的领域事件模型,任何实体都可以挂接这个对象,发布消息,或关注感兴趣的消息并做出响应,这个部分与通用的事件模型并没有太大的不同,示意图如图7所示。

③设计仓储
使用仓储模式可以很好地隔离数据库的操作和领域对象。

在领域层,作者定义了各个仓储接口,仓储与聚合根或实体一一对应,包含对应的增删改查等操作,它们是数据库操作的接口。

需要注意的是,在领域层中,只是定义了接口,并没有具体的持久化的实现。具体的持久化工作放在了基础设施层中。

3) 其他层的一些细节
①基础设施层
这里重点说明一下的是数据库持久化的选型。针对领域层提供的仓储接口,作者实现时选择了使用Enti⁃ty Framework Core(以下简称EF Core) 作为基础框架。使用此类ORM框架大大简化了数据库的操作,使用对象而不是SQL语句的方式可以避免很多语法上的错误,有效地提升了代码的健壮性。

而且使用了EF Core的Code First的方式后,项目只要使用EF Core的包命令就可以非常简单地根据实体对象的变更来创建和维护数据库。

②应用服务层
在该项目中,应用服务层比较简单,它实现了一个公用的AppService,封装了公用的分页的逻辑。其他各项服务比如BookAppService都继承自该基类,实现了自己的逻辑。

在各个服务中,为了调用领域层的业务逻辑,首先需要把前端传过来的输入数据传输对象(Data Transfer Object,以下简称DTO) 转换成领域层的数据模型,然后调用领域层的领域模型和基础设施层的对象完成功能,最后再将结果转换成输出DTO返回给前端。

③后端接口层和前端表现层
接口层使用Restful Api去提供服务,前端表现层使用Vue3.0实现展示,不管是否使用DDD,这些部分都是一样的,不去多解释。
经过上述的分析、设计与重构,最终得到如下新的架构,如图8所示。

3 结束语

采用了DDD来开发和管理项目以后,项目的业务逻辑沉淀到了领域层的领域对象中,领域对象变成了包含业务逻辑的充血模型,这样业务逻辑得到了复用,程序的扩展性得到了保证。

此外,由于存在清晰明确的分层和职责,团队日常的开发效率得到了显著的提升。目前该站点已经上线并稳定地运行至今。

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

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

相关文章

电缆故障检测仪技术参数

一、电缆故障测试仪的技术参数 1.采样方法:低压脉冲法、冲击闪络法、速度测量法 2.电缆长度:50m、300m、1km、2km、5km、10km、30km、60km 3.波速设置:交联乙烯、聚氯乙烯、油浸纸、不滴油和未知类型自设定 4.冲击高压:35kV及以下…

linux基本功系列之cd命令实战

文章目录 前言一. cd命令的介绍二. 语法格式及常用选项三. 参考案例总结 前言 居然发现了落下了CD命令,也不算落下把,主要是cd命令内容太少,撑不起一篇文章,今天也写一写,就当记个笔记吧 🏠个人主页&#…

业务逻辑漏洞之支付逻辑漏洞

业务逻辑漏洞之支付逻辑漏洞 一、漏洞挖掘介绍二、Web漏洞产生的原因三、业务逻辑简述四、 常见业务逻辑漏洞的功能点五、支付逻辑漏洞5.1、漏洞背景5.2、产生原因5.3、测试方法 六、挖到这些漏洞有什么用? 一、漏洞挖掘介绍 漏洞定义: 官方定义&#…

策略模式——算法的封装与切换

1、简介 1.1、概述 在软件开发中,常常会遇到这种情况,实现某一个功能有多条途径。每一条途径对应一种算法,此时可以使用一种设计模式来实现灵活地选择解决途径,也能够方便地增加新的解决途径。为了适应算法灵活性而产生的设计模…

opencv35-形态学操作-腐蚀cv2.erode()

形态学,即数学形态学(Mathematical Morphology),是图像处理过程中一个非常重要的研 究方向。形态学主要从图像内提取分量信息,该分量信息通常对于表达和描绘图像的形状具有 重要意义,通常是图像理解时所使用…

【零基础学Rust | 基础系列 | 函数,语句和表达式】函数的定义,使用和特性

文章标题 简介一,函数1,函数的定义2,函数的调用3,函数的参数4,函数的返回值 二,语句和表达式1,语句2,表达式 总结: 简介 在Rust编程中,函数,语句…

MySQL数据库安装(二)

夕阳留恋的不是黄昏,而是朝阳 上一章简单介绍了MySQL数据库概述(一), 如果没有看过, 请观看上一章 一. MySQL 卸载 一.一 停止MySQL服务 在卸载之前,先停止MySQL8.0的服务。按键盘上的“Ctrl Alt Delete”组合键,打开“任务管理器”对话…

类的多态性(JAVA)

目录 多态 重写 向上转型 类的多态性例子: 多态的优缺点 多态 所有的OOP语言都会有三个特征: 封装(点击可跳转)继承(点击可跳转)多态 多态体现:在代码运行时,当传递不同类对…

8.3day04git+数据结构

文章目录 git版本控制学习高性能的单机管理主机的心跳服务算法题 git版本控制学习 一个免费开源,分布式的代码版本控制系统,帮助开发团队维护代码 作用:记录代码内容,切换代码版本,多人开发时高效合并代码内容 安装g…

GROW模型及其应用

一、作用 提供一套可操作的流程来理清现状,创造专注,减少干扰,使执行人从内心找到下阶段目标与达成目标的实施办法。是一套主要用于沟通、绩效辅导中的方法。 二、是什么 GROW模型由确定目标(Goal)、了解现状&…

神经网络的搭建与各层分析

为什么去西藏的人都会感觉很治愈 拉萨的老中医是这么说的 缺氧脑子短路,很多事想不起来,就会感觉很幸福 一、卷积层 解释:卷积层通过卷积操作对输入数据进行处理。它使用一组可学习的滤波器(也称为卷积核或特征检测器&#xff09…

hive通过外表整合es,超详细过程。

参考官网 Apache Hive integration | Elasticsearch for Apache Hadoop [7.17] | Elastic 官网的介绍很简单,我看了很多博客,写的也很简单,但是我搞了半天才勉强成功,分享下,免得各位多走弯路。 环境准备 官网也很…

论文研读|生成式文本隐写发展综述

前言:最近接触了文本隐写这一研究领域,大概率以后深入这个方向开展研究,以下是本人近日对该领域研究现状的调研总结,以及生成式文本隐写代表性工作的相关介绍,便于厘清生成式文本隐写的发展脉络以及探寻未来研究空间。…

Go学习第三天

map的三种声明定义方式 声明map后,一定要make开辟空间,否则会报越界且不能使用 package mainimport "fmt"func main() {// 第一种声明方式// 声明myMap1是一种map类型 key是string value是stringvar myMap1 map[string]string// 判断一下map在…

接口请求(get、post、head等)详解

一.接口请求的六种常见方式: 1、Get 向特定资源发出请求(请求指定页面信息,并返回实体主体) 2、Post 向指定资源提交数据进行处理请求(提交表单、上传文件),又可能导致新的资源的建…

【高光谱图像的去噪算法】通过全变异最小化对受激拉曼光谱图像进行去噪研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

HCIP 交换综合实验--企业三层架构

题目 1、内网IP地址使用172.16.0.0/26分配 2、SW1和SW2之间互为备份 3、VRRP/STP/VLAN/Eth-trunk均使用 4、所有PC均通过DHCP获取IP地址 5、ISP只能配置IP地址 6、所有电脑可以正常访问ISP路由器环回 实验步骤 第一步、规划IP地址 R1-R2:100.1.1.0/24 R2-LSW1…

【远程桌面软件NoMachine】

Remote Access for Everybody 特色:快速、安全、跨平台、免费且简单易用,尤其是在带宽低、速率慢的网络环境下,NoMachine仍能保持良好的性能。 官网地址为:https://www.nomachine.com/

c++--简单多状态动态规划问题

PS:以下代码均为C实现 1.按摩师 力扣 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总…

【JAVA】正则表达式是啥?

个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 文章目录 前言正则表达式正则表达式语法正则表达式的特点捕获组实例 前言 如果我们想要判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”)&#xff0c…