当前位置: 首页 > article >正文

一篇带你了解大厂都在用的DDD领域驱动设计

一、DDD到底是什么

DDD全称Domain Driven Design,领域驱动设计。

为了解决快速变化、复杂系统的设计问题的

领域驱动设计是Eric Evans在2004年发表的Domain Driven Design(领域驱动设计,DDD)著作中提出的一种从系统分析到软件建模的一套方法论。以领域为核心驱动力的设计体系。

从领域驱动定义来看,领域驱动设计-软件核心复杂性应对之道,从Eric 定义中可以看出,领域驱动设计是为了解决复杂的软件设计,而且只是解决软件复杂性的一种方式,并不是唯一选择。另外不是所有的业务服务都合适做DDD架构,DDD适合产品化,可持续迭代,业务逻辑足够复杂的业务系统,对于系统初期业务逻辑相对比较简单的应用,传统MVC架构更具有优势,可以减少一部分认知成本与开发成本。而且领域驱动设计并不是万金油,只是解决复杂软件的一种方案,领域驱动设计本身只提供了理论思想,具体的落地方案一定是结合具体的业务场景实现的。

从领域驱动对应关系来看,一方面目前很多建设中台的时候大多采用DDD思想落地,DDD很多思想比如领域划分,领域事件,领域服务,边界上下文划分,充血模型,代码防腐,统一语义等等可以很好的帮助实现中台的落地,但是中台落地DDD并不是唯一选择。另一方面对于DDD的这些思想,与DDD的关系更多是聚合关系,而不是组合关系,也就是在具体应用开发中,即使采用传统的MVC架构,这些思想依然可以很好的发挥其作用。

二、DDD的由来

早期都是面向过程的代码,发现很难做到复用,结构体复用,对于结构体操作operatioin不能复用

于是就诞生了面向对象,属性和方法的统一。

需求不断变化,并且需要从产品客户不断平滑的传递到研发端,进入了第一次软件危机

第一次软件危机解决:敏捷开发-TDD-快速原型-MVC-Spring-ORM 

2003年DDD诞生,201X年,微服务流行,业务的快速发展-团队快速膨胀,于是DDD就来了

三、MVC到DDD的演进

先来看看mvc三层结构的代码

包的组织:

  • controller
  • service
  • dao

再来看看DDD架构下的代码

1、抽象CheckService,应对业务变化(防腐层)

业务检查也放到了checkService里面,因为这个选课的业务检查是可以换的,今年可以这样,明年可以那样,我们只需要那service抽出来,换具体实现就可以了,这样业务代码就不用变了。从而实现应对业务变化,这个也叫防腐层

2、抽象MQ基础设施层,防止第三方组件的变化(rocketMQ0->kafka)

另外我现在的MQ可能是kafka直接templete来set过去,如果我的mq不用kafka那么标准格式就得跟着变,我们的基础支撑层是不会确定用哪种mq,会在mq上面封装一个msgSender,在他的实现类里完全可以有各种mq来实现,假如我要换一直mq的话只要实现msgSender就可以了

3、贫血模型vs充血模型

充血模型和其他充血模型怎么做交互?

Student假如是贫血模型,会被各种sevice调用,选课,借书,体育等等,会分布到各个业务中,你还敢改student信息吗?除非你读懂每一个servcie的调用过程!

改成冲血模型,加入upgrade和run等和自身相关的业务逻辑

比如我现在有个学生领域和课程领域,我们可以单独有个服务交选课service(领域服务),来做他们两个的业务逻辑,将来我们假如他们有了新的业务,只需要在这里面加就行了,然后他们各自领域内自治,可以自我发展。

充血模型是怎么和数据库打交道的?

我们知道存储可以是各式各样的, 我们一般用仓库StudentRepository来管理Student的存储,他也是个抽象层防腐层,可以用MqSQL也好MongoDB也好具体落地

如果是复杂的对象,我们就可以用工厂模式,仓库中集成Factory/Builder应对复杂对象的组装。student里面除了有简单的属性id,name,age,可能还有address要存到另一个库里面,phone要看是不是骚扰号码存另一个库,这种复杂就需要用到组装器来组装

4、他们的对比

MVC保证了实现最差也不会差到那里去(但基本总是最差),DDD如果做的不好,可能比MVC还差,领域之间划分不清晰,可能会浪费很长一段时间也很难落地。如果做的好,确实可以做到应对业务变化(得非常了解业务,预测业务变化才能做到),也不会出现屎山代码。总的来说要让DDD真正落地,需要公司工程师有很高的素质。

5、DDD和微服务的关系

其实DDD和微服务没有什么关系,DDD是设计思想,微服务是具体实现。DDD可以用微服务实现也可以用单体来实现。如果是上面的例子,两个领域学生和课程。全部放一起就是单体,单体上学生域到课程域的领域服务单体也可以实现;如果是微服务,他们之间的领域服务可能用rpc来实现,也可用中间件来实现。


http://www.kler.cn/a/16415.html

相关文章:

  • 深入探索离散 Hopfield 神经网络
  • Java算法OJ(7)随机快速排序
  • ubuntu连接orangepi-zero-2w桌面的几种方法
  • 从0开始学习Linux——文件管理
  • linux c/c++最高效的计时方法
  • 【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线
  • 【Canvas入门】从零开始在Canvas上绘制简单的动画
  • 高性能定时器介绍及代码逐行解析--时间堆
  • 走进小程序【十一】微信小程序【使用Echarts 和 腾讯地图】
  • R语言 | 数据框
  • MySQL数据库——MySQL修改视图(ALTER VIEW)
  • vim 常用操作(vimtutor阅读笔记)
  • 移动宽带安装说明一(刘欣)
  • 【第十一届泰迪杯B题】产品订单的数据分析与需求预测
  • Netty小白入门教程
  • tensorflow中Keras ---图像预处理----tf.keras.preprocessing.image.ImageDataGenerator 类
  • P1915 [NOI2010] 成长快乐
  • 三元操作 三元操作符 if-else / ? :
  • 进程控制下篇
  • [LeetCode]1033. 移动石子直到连续
  • 《基于光电容积法和机器学习的冠状动脉疾病患者出血风险预测》阅读笔记
  • 【Python2.x与Python3.x的区别】
  • 进程相关(创建-回收-exec-守护进程)
  • 【华为OD机试 2023最新 】任务总执行时长(C语言题解 100%)
  • BPMN2.0 任务-服务任务
  • LVS负载均衡集群--DR模式