作者:小傅哥
博客:https://bugstack.cn
原文:https://mp.weixin.qq.com/s/ezd-6xkRiNfPH1lGwhLd8Q
积淀、分享、成长,让本人和别人都能有所播种!😄
一、前言
领导:为什么要应用 DDD?
我也苦思冥想,怎么跟领导说咱们从 MVC 降级到 DDD 吧,因为 DDD 代码构造更加清晰、畛域驱动比测试驱动开发更加先进、研发的兄弟们也更想用用新框架等。
不过这么聊被喷一顿不说,还得说你是适度设计瞎折腾,咋回事呢?因为没聊到重点呀,你 MVC 降级 DDD;给业务带来了什么
、 晋升了交付效率吗
、 升高了公司研发老本吗
,都没有?不仅没有,你还说为了前期的迭代保护,后期会须要更多的设计和开发工夫。咋?你是想这一个 Q 就把我送走吗,我刚来咱们部门 KPI 在那悬着,压的我头发都白了!别瞎搞,求稳!
那就不搞了吗?搞哇,不让搞换领导!但搞之前,要思考分明,DDD 不是 Silver Bullet,你有一腔热血虽好,可是也得通晓 DDD 的设计准则是什么、它更适宜的场景是什么、与 MVC 比照有什么云泥之别。
二、开发成本
应用 DDD 模式开发代码的老本到底在哪?是因为应用 DDD 四层分层构造
就比MVC 三层分层构造
更浪费时间吗?其实并不是,因为四层构造绝对于三层构造,反而更好的辨别了代码所属职责,在相熟模块性能职责后,开发起来也会更加顺畅。
那这里的 DDD 畛域驱动设计开发的老本在哪呢?这个老本在于对于一个 简单零碎又尚未 在开发后期就有十分短缺的教训来 拆分职责边界
、 划分性能畛域
、 明确编排逻辑
和对未知流程扩大的把控上
,所带来的 风暴模型设计老本。
而通常应用的 MVC 构造根本不会呈现这样的问题,因为在理论的代码中,DAO、PO、VO 等都是共用的,大家在开发代码的时候,像 堆泥球
一样 面向过程写代码
,间接串联出产品的 PRD 性能节点即可,不必过多的思考解耦和内聚。
那不是能够设计模式吗,这就须要看你是站在哪个维度去思考问题。设计模式在这里是战术问题的,DDD 和 MVC 是确定策略问题的,有点像是说:“方向不对,致力徒劳一样”
那么当初咱们再来看这条开发成本曲线:
- 与其余两种分层构造绝对比,应用 DDD 的时候,须要在后期投入较多的工夫老本来设计领域建模,所以后期老本会更高一些。
- 但随着业务一直迭代后的逻辑的复杂性减少,DDD 零碎架构所开发的代码稳定性会更好,也就阐明 DDD 更容易扩容和保护。
- 所以框架结构的更换,不是最终减少开发成本的中央,如果你不做领域建模也不做更多的设计思考,那么即便是 DDD 的四层架构,也能让你写出 MVC 的成果。而那些对业务场景经验丰富的架构师或者研发人员,曾经十分明确了各个业务性能的职责边界,要实现一个零碎需要须要实现哪些外围畛域服务,再这样的状况用 DDD 也不会带来多少开发成本,反而更加熟能生巧了!这就是为什么说,须要领域专家,因为专家曾经积攒了很多的策略设计教训
- 此外应用 DDD 畛域驱动设计的模式进行开发,除了解决需要的迭代老本,更多的时候是要面对公司策略调整后,零碎的交接、人员的更替和新增,都要在原有的工程架构下持续迭代开发,否则就要颠覆从新做,那样所面临的更替老本将更大,同时又是开发了一个与人员绑定不易于交接保护的工程代码。
三、架构比照
在理解和把握 DDD 畛域驱动设计的路上,你肯定会碰到两个形象的钉子 ——“贫血模型”、“充血模型”:
- 贫血模型:事务脚本模式,最早起源于 EJB2,到 Spring 进入开“春”盛世。
- 充血模型 :畛域模型模式,2003 年提出,始终到
《实现畛域驱动设计》
的问世,才开启了 DDD 的大门。但国内直到微服务、低代码的衰亡,才开始 DDD 热
1. MVC
MVC 分层构造将:“状态”(数据,成员对象)、“行为“(逻辑、过程),拆散到不同的对象中,只有状态的对象(VO -> Value Object) 被称为贫血模型,只有行为的对象,就是框架分层中常见的 Logic/Service/Manager 层(对应到 EJB2 中的 Stateless Session Bean)
- 以应用层 Service 应用 DAO、PO 基础设施包装业务逻辑的开发方式,乍一看认为应用层是在对领域建模的实现,”畛域层“有着丰盛的对象链接,和真正的畛域模型也十分相似,但当咱们代码随着业务性能逻辑的逐渐实现中会缓缓发现,咱们写了一堆的
get/set
对象,而他们被重复穿插应用,没有与任何畛域聚合,也就是不具备任何的行为动作,只是一堆贫血模型对象。 - 这种反模式的设计,其实齐全与
面向对象
的设计是南辕北辙的,面向对象的设计更心愿行为和数据绑定在一起,与之比照的贫血模型更像是面向过程设计。 - 在 MVC 分层构造下,所有的行为都被写入到 Service 对象中,最终你会失去一组事务处理的过程脚本,从而完满的避开了畛域模型设计所带来的益处(清晰的职责边界、聚合的性能服务、清晰的面向对象)。
2. DDD
DDD 的分层构造也是面向对象编程的实质:”一个对象领有行为和数据“,在畛域层包含了:对象、聚合对象、仓储和 Service 实现。
- DDD 的分层构造更重视 Domain 畛域层的实现,由很薄的应用层定义接口和编排接口,由畛域层做具体的实现。
- 所有的业务逻辑都依照各自的职责边界拆分成一块块的性能畛域,每一个性能畛域都是充血模型的构造的具体实现。
- 那么这样的代码最终实现当前,无论在迭代、保护、人员更替,都能很好依照畛域设计文档找到对应的代码实现进行开发。
四、设计准则
首先 DDD 的设计分为策略和战术;
- 策略设计:从业务视角登程,建设业务畛域模型、划分职责边界,建设通用语言的界线上下文。顶层策略设计构建的畛域模型构造,是整个服务前期编排的重点,它确定了性能的职责边界、聚合、对象等,也就相对了前期服务战术实现的开发和交付品质。器重策略,能力落地好战术!
- 战术设计:从技术视角登程,侧重于畛域模型的技术实现,实现性能开发和交付落地。畛域设计的重点包含:实体、聚合对象、值对象、畛域服务、仓储,还有一个十分重点的
设计模式
。任何一个较为简单的畛域模型实现都须要思考设计模式的应用,否则即便策略优良,战术也无能回 MVC 去。
在以 DDD 畛域驱动设计落地的过程中,要依附畛域驱动设计的设计思维,通过事件风暴建设畛域模型,正当划分畛域逻辑和物理边界,建设畛域对象及服务矩阵和服务架构图,定义合乎 DDD 分层架构思维的代码构造模型,保障业务模型与代码模型的一致性。通过上述设计思维、办法和过程,领导团队依照 DDD 设计思维实现微服务设计和开发。
- 回绝泥球小单体、回绝净化性能与服务、回绝加性能排期一个月
- 架构出高可用极易合乎互联网高速迭代的应用服务
- 物料化、组装化、可编排的服务,进步人效
- 要畛域驱动设计,而不是数据驱动设计,也不是界面驱动设计
- 要职能清晰的分层,而不是什么都放的大箩筐
DDD 的畛域模型设计,界线内的上下文,能够拆分为独立的微服务。但不仅要从业务视角看问题,也要思考非业务的技术因素,包含:高性能、平安、团队、技术异构等,这些非业务的技术因素,也会决定畛域模型落地的具体落地。
五、举个例子
你说我 MVC 不好,你说我 MVC 贫血模型,PO 类一直的收缩,但让我用 DDD 又都是实践,程序员更喜爱看的是曾经落地的代码,通知我怎么干。
为什么这么难落地呢?因为从 MVC 适度到 DDD 形容比照 只是积攒了 MVC 失败的教训,但没有 DDD 胜利的教训
,所以更多的时候想落地 DDD 除了有实践撑持,更须要一份案例摆在面前。
1. 工程构造
所以为了让更多的码农看到在 DDD 上一条能走的路,专门折腾了个 DDD 分布式抽奖零碎
,来通知大家怎么应用 DDD 开发业务需要;
整体零碎架构设计蕴含了 6 个工程:
- Lottery:分布式部署的抽奖服务零碎,提供抽奖业务畛域性能,以分布式部署的形式提供 RPC 服务。
- Lottery-API:网关 API 服务,提供;H5 页面抽奖、公众号开发回复音讯抽奖。
- Lottery-Front:C 端用户零碎,vue H5 lucky-canvas 大转盘抽奖界面,解说 vue 工程创立、引入模块、开发接口、跨域拜访和性能实现
- Lottery-ERP:B 端经营零碎,满足经营人员对于流动的查问、配置、批改、审核等操作。
- DB-Router:分库分表路由组件,开发一个基于 HashMap 外围设计原理,应用哈希散列 + 扰动函数的形式,把数据散列到多个库表中的组件,并验证应用。
- Lottery-Test:测试验证零碎,用于测试验证 RPC 服务、零碎性能调用的测试零碎。
2. 流程拆解
当咱们拿到产品的 RPD 当前,并不是间接上手开发,而是须要从流程中拆解出一份面向对象设计的畛域服务,举例;
- 拆解性能流程,提炼畛域服务,一步步教会你把一个业务性能流程如何拆解为各个职责边界下的畛域模块,在通过把开发好的畛域服务在应用层进行串联,提供整个服务链路。
- 通过这样的设计和落地思维,以及在把流程化的性能依照面向对象的思路应用设计模式进行设计,让每一步代码都变得清晰易懂,这样实现进去的代码也就更加易于保护和扩大了。
- 所以,你在这个过程中学会的不只是代码开发,还有更多的落地思维实际在这外面体现进去。也能为你当前开发这样的一个我的项目或者在面试过程中,一些理论简单场景问题的设计思路,打下不错的根底。
3. 一起实际
如果你对 DDD 实际学习的事件感兴趣,也能够一起退出 DDD 分布式抽奖零碎
的实际,来排汇一份能落地的教训。PS:给本人花点钱,做有价值的投资,就当少买个皮肤了
学习链接:https://bugstack.cn/md/project/lottery/introduce/Lottery%E6%8A%BD%E5%A5%96%E7%B3%BB%E7%BB%9F.html
- 具备 Java 编程根底的研发人员,想晋升本人的技术能力
- 心愿晋升编码思维,剔除到代码中的坏滋味
- 有志愿成为架构师,但还处在肯定瓶颈期
- 想退出大厂做码农,但总感觉找不到门路
六、总结
- DDD 并不是 Silver Bullet,你并不能指望换个了个框架结构,就能扭转堆屎山⛰似的开发代码,所带来坏滋味问题。MVC 构造一样能够开发出好的代码,只是它的稳定性更差,不利于长期保护和迭代。
- DDD 的复杂性是因为短少领域建模的教训,如果同一个需要你曾经在 MVC 的中嚯嚯的排汇了足够的边界上下文总结,当初换 DDD 能够让你更快的开发代码。
- DDD 也并不是所有工程模型构造都简单,DDD 是指导思想,你能够在 DDD 四层架构中因为引入 RPC 拆解各个模块的分层,也能够因业务规模在中等及复杂度时不引入 RPC 框架,这样的 DDD 会更加短小精干,与 MVC 相比只是在畛域层定义接口,把代码放到 domain 层做实现,数据放到仓储层解决。参考代码:https://github.com/fuzhengwei/CodeGuide