每过一段时间,就会有人跳出来批判 DDD,这东西到底是垃圾还是银弹?

在某某公司干活的时候,有一批人声称要用 DDD 改造老旧系统,彻底解决核心流程规模化之后,项目难以维护的问题。之前某篇文章里的这张图,就是在用 DDD 做项目重构之前的烂摊子:

大家都很聪明,聪明到最后没人知道这新需求到底该往哪里写了。架构师们聚在一起学习 DDD 精神,产出学习报告,大半年过去,终于出了一些成果,有些子项目完成了用 DDD 进行的重构,年底可以拿来在酒会上邀功了,这下我们跟上了业界业务开发的主流方法论,可喜可贺,可喜可贺啊。

年末的时候部门内匿名提问的小纸条却向架构师们发直球:“为什么用了 DDD 以后,代码更难懂了?”,当时引得各位 DDD 推手尴尬无比,只能搪塞过去。

所以你觉得我是要批判么?那倒不是。

在某某司工作期间,到离职前,我把市面上所有 DDD 相关的书全部看了一遍。对其理论体系进行了完整的了解,可以说这套理论还是有些用处的,DDD 的理论诞生时间比较早,微服务的趋势是后来才爆发的。但微服务刚开始没有明确的拆分指导,人们发现 DDD 里的 bounded context 好像看着正好和服务的粒度是可以做个对应的,DDD 就成为了很多公司做业务的绝对主流方法论。

虽然很多技术人员不爱听,但是技术优劣和商业成败其实没什么必然的联系。同样的,方法论的对错和项目的成功与否也没有必然的关系。很多大公司做业务的人出来讲他们的技术方法论,这些人可能连自己的项目为啥成功都不一定知道,你指望能对你的场景产生直接帮助那可能是想多了。只是当听个乐,得个借鉴那可能还没什么问题。真的当金科玉律去执行,那撞一头包也正常。

DDD 和其它的工程方法论一样,没有办法证伪。放眼望去,纯粹堆砌人肉电池,不用 DDD 的项目也那么多成功的,大家的屁股还是在跟着公司的市值跑,哪家公司市值涨到中国第一了,那他们的技术就牛逼,这叫看市值决定价值观。如果一家公司靠 996 成功了,那 996 就是商业致胜的法宝,不学你就落后了。屁股可以决定脑袋嘛。

不过作为一个矜持的技术人员,我们在批判方法论的时候,还是应该要先对敌人有一些了解。

所以这一篇,我就简单带你们看看 DDD 里那些鬼名词都是什么意思。

战术设计与战略设计

整个 DDD 的方法论可以划分为两个大模块,战术设计、战略设计。这个你顾名思义,战术是小,战略是大。

  • 战术设计指的就是单模块级的设计,基本都是纯技术范畴的东西,只DDD 中给代码命名和模块设计给出了一些指导方法

  • 战略设计指的是大项目的模块拆分,这个和一线程序员关系不大,主要是公司内怎么在 bu 之间切蛋糕,bu 内怎么在 team 之间分赃

现在很多校招程序员可能或多或少都会碰到一些 OOP 方面的面试题,比如三大特性五大原则之类的,这些原则是设计项目的时候可以参考的原则, DDD 的战术设计就是在单模块上的各种命名规则和设计方法。只不过 OOP 这些原则的发明人(严格的说应该是汇总人)是 uncle bob,就是 《clean code》,《clean architecture》 的作者,这位白胡子爷爷大概率和 DDD 社区是尿不到一个壶里的,所以 《clean architecture》 这本书里只字未提 DDD。

公司的业务要怎么分派给不同的 bu(部门)去完成,这个一般是公司 CTO 或者 GM 要做的事情,部门内的项目要怎么分,哪些组做哪些事情。这是战略设计的范畴。DDD 声称战略设计也是要有方法的。这部分也是很多程序员认为最没用的一部分,我们后面来批判一下这些程序员。

战术设计

战术设计是纯技术范畴的东西,最让人头痛的就是里面的名词。

贫血模式和充血模式:DDD 推荐你用充血模式写代码,也就是按 OOP 的方式去做抽象,然后把行为挂在对象上,而不是以纯过程式 的方法去写代码。所谓的充血,就是对象本身有很多关联的行为,而不只是一个单纯的数据库的表的字段映射。DDD 声称的充血模式的优势是,大部分的行为被封装到了对象内部,这样我们在阅读流程代码的时候,是一目了然的,直接能看到 step 1,step 2,step 3。但实际即使我们不用 OOP 来组织行为,一样可以把不同的业务 step 做好封装和复用。有些公司的服务粒度拆的特别细,比如只有 5000-10000 行代码,在 DDD 里声称的充血模式的优势没有那么明显。

值对象和实体:这个也挺离谱的,值对象就是纯粹的数值、文本类型,比如:

type person struct {age intname string
}

就是值对象,如果我们给这个 person 加一个 id,让它能表示 person 的唯一性了;

type person struct {id  intage intname string
}

那它就是实体了。

这两个概念只是给我们日常用的对象们进行了一个简单的分类,没什么大用处。

聚合根:DDD 里所谓的聚合根是事务粒度的 entity,也就是说,如果我们对 db 进行存取,那么我们就需要有一个聚合根,如果在一个事务里需要操作多张表,那么就需要给多张表关联一个单独的聚合根。

聚合根可以由一个 entity 组成,也可以由多个 entity 组成,就是你完成一个 db 事务的时候有多少关联的对象 ,那可能就有多少在同一个聚合根下面的 entity。

六边形架构:这个所谓的六边形架构,就是除了业务以外的所有外部变化都抽象成 adapter interface 做适配。如果你稍微理解一点点点依赖反转,那应该知道怎么样去做这种抽象。如果你一点都不了解,那我建议你去看看 go-micro 的代码。如果看不懂,建议还是尽早转行吧~

六边形架构这东西主要是名字实在起的太奇怪,在 《clean architecture》那本书里,uncle bob 也给过一张图:

《evolutionary architecture》这本书出自造词大本营 thoughtworks 的员工之手,里面有一个 plugin architecture,就是有些人特别喜欢说的插件化架构:

Repo Pattern:DDD 理论认为我们业务项目的存储这一层是可能经常变化的,所以就专门存储层的 interface 设计单独拿出来,称为 Repo Pattern,这东西实在没啥可说的,find,getlist,save,你只要有一点点 orm 经验,里面有啥接口应该自己都可以默写出来。

事实是在 2021 年,我们的存储系统基本是不太可能做切换的了,即使切换,那些新兴的社区存储系统也会支持 MySQL 协议,基础设施想要侵入代码,那简单是大逆不道啊。

领域事件:其实就是做上下游解耦的 kafka message,我们用 domain event 显得会更洋气一些。

领域服务:Domain service,顾名思义,你认为是自己部门或者组内的局部 api gateway 也是可以的。

综上,如果你是在大公司一线工作了两三年的程序员,上面这些东西应该马上就能理解,没有啥值得说的。如果是为了去架构师大会上秀一秀,你总得包装一下让自己显得没那么土吧?

战略设计

Domain:领域,你们公司是干啥的,你都不知道吗?

Core Domain:你们公司的卖货的,那卖货就是你们与其它竞争对手的关键竞争环节。这就是核心域,就是核心业务,为啥聪明人都往核心业务挤?核心业务的汤也比边缘业务的饭好啊。

SubDomain:你们公司的卖货的,但是用户没法付钱,那也没法干,支付就是子领域。

Supporting Domain:你们公司是卖货的,但是客户想看一些指标,你总得有系统能支持吧?可能就是些写写 SQL 的系统。支持域。

Generic Domain:你管你们公司干什么呢?员工的在职离职,工资发放总得有系统能支持吧,这些就是通用域。

除了第一个 Domain ,其余四个 domain 重要性逐级递减,递减的意思是,如果公司要裁员,那是从下面往上面裁。

前面我说有些程序员觉得 DDD 战略设计没用,你连自己所在的组,从事的工作职责对于公司来说重不重要都不清楚,那被裁的时候也别哭哦。

统一语言:这个就更好理解了,比如跳水这个词,你说跳水的时候指的是这个:

而你同事说跳水的时候指的是这个:

这里你们聊的是工作,那说明你们一定不是在同一个上下文里工作,可能你们俩一个在体育赛事部门,另一个可能是在金融部门, DDD 认为可以用统一语言来进行领域划分工作。划分后在同一个上下文内,同一个名词大家说出来意思一致。这就是 Bounded Context,  ain。

既然拆分了,如果我们还在同一个 domain 内,那完成业务流程是需要协作的,这个不同 Context 的协作方式就叫 Context Maps 或者 Integration Type。

名词很恶心,但具体的方法就两种,两个微服务要么通过 RPC 通信,要么通过 MQ 通信。

如果通过 RPC 通信,那 callee 一般是 caller 的爹,很多时候 callee 挂了是要影响 caller 的(当然也有熔断之类的方法避免一起死)。

通过通过 MQ 通信,那上游一般是下游的爹,因为上游一个重构,下游们可能就都炸了,最终一致都是屁话,多少公司的最终一致都是靠人肉修的。

这种爹和儿子的关系就是 Conformist。如果爹能多考虑一下儿子的需求,那就是 Customer-Supplier 关系,毕竟顾客名义上还是上帝。如果跨系统有一些需要共享的定义,比如公司里的业务分类,可能大家都要从某个系统的 PHP 文件里解析出来在自己的系统里去用,那这时候可能得去使用别人的代码,这种叫 Shared-Kernel,Kernel 一改,大家一起死。

最后,有时候我们可以用一个叫 ACL 的东西拦住上游的一些修改对我们的业务逻辑侵入:

防腐层:Anti-Corruption-Layer,就是我要把外部系统的变化拦截在对接层,不要让别人的屎甩到我身上。

讲到这里,基本的概念我们已经都过一遍了,你要说 DDD 一点用处都没有,那我也是不同意的,至少看完了这些书,我知道去哪里能赚到更多的钱了。

额外再说一句,DDD 的书写的都不怎么样。

DDD 到底是银弹还是垃圾相关推荐

  1. java 垃圾回收 null_java方法中把对象置null,到底能不能加速垃圾回收

    今天逛脉脉,看见匿名区有人说java中把对做置null,这种做法很菜,不能加速垃圾回收,但是我看到就觉得呵呵了,我是觉得可以加速置null对象回收的. 测试的过程中,费劲的是要指定一个合理的测试堆大小 ...

  2. 低代码到底是银弹,还是行业毒瘤?

    作者陈旭,中兴低代码开发平台 Awade 的架构师和负责人.Awade 目前已成为中兴通讯低代码平台事实上的标准,基于它开发的 App 随着中兴通讯的产品遍布国内各大运营商,以及其他多个国家的知名运营 ...

  3. 【C语言】转义字符\xhh和\ddd到底如何判断?被兔子个数支配的恐惧你也有吗?(每日小细节001)

    前言: 欢迎打开这篇博客,从今天开始,每天和大家分享一个C语言小细节,不久之后还会追加C++ 一些常常被忽视的小细节和思想统一的编程题目是这个专栏的核心哦 虽然简单但千万别在细节处失分!!!! 感兴趣 ...

  4. JVM如何识别“到底谁才是垃圾“?

    什么样的对象可以称为垃圾对象?换句话说:在垃圾收集器工作的时候,那些对象是可以被回收的,哪些对象是不可以被回收的?判断的标准是什么?系统中的对象千千万,怎么才能准确无误的找出来并"杀&quo ...

  5. 中台架构与实现:基于ddd和微服务 下载_为什么在做微服务设计的时候需要DDD?...

    记得之前在规划和设计微服务架构的时候,张队长给了我一个至今依然记忆深刻的提示:『你的设计蓝图里为什么没有看到DDD的影子呢?』 随着对充血模型的领域认知的加深,我越加感觉到DDD的重要性.但是DDD内 ...

  6. 为什么在做微服务设计的时候需要DDD?

    点击上方"程序猿技术大咖",关注并选择"设为星标" 回复"加群"获取入群讨论资格! 记得之前在规划和设计微服务架构的时候,给了我一个至今依然 ...

  7. 商品领域ddd_DDD第1篇 - 为什么使用DDD?

    认真写文章,用心做分享. 个人网站:yasinshaw.com 公众号:xy的技术圈 先说声抱歉,最近两三个星期都没有产出新的文章了.一方面是忙(懒):另一方面是在想能写什么题材,毕竟日常开发中遇到能 ...

  8. 如何使用 DSL 实现 DDD 的快速落地

    开发大型软件最难的部分并不是实现,而是要深刻理解它所服务的现实世界的领域.领域驱动设计(Domain-Driven Design,DDD) 是一种处理高度复杂领域的愿景(Vision)和方法,它主张在 ...

  9. 【数据挖掘】贝叶斯公式在垃圾邮件过滤中的应用 ( 先验概率 | 似然概率 | 后验概率 )

    文章目录 I . 垃圾邮件过滤 需求 及 表示方法 II . 贝叶斯方法 步骤 1 : 提出假设 III . 贝叶斯方法 步骤 2 : 计算垃圾邮件假设概率 IV . 贝叶斯方法 步骤 2 : 计算正 ...

最新文章

  1. SWIG和PInvoke学习(1)
  2. python基础教程3-Python基础教程(三)
  3. jvm性能调优 - 02JVM中内存区域
  4. boost::container实现显式实例化列表的测试程序
  5. 同步屏障CyclicBarrier
  6. RPA如何助力企业解决人才短缺难题?
  7. android hook截取其他程序的按钮事件_Hook技术
  8. python静默打印pdf_前端静默打印实现 html pdf集合
  9. shell脚本 猜数字游戏并计数比较次数
  10. serve : 无法加载文件 C:\Users\wb\AppData\Roaming\npm\serve.ps1
  11. eclipse运行maven项目,tomcat启动报错
  12. 【数据结构(C语言)】数据结构-图
  13. 【架构解密】第六章 深入解析分布式存储
  14. 智慧博物馆信息系统建设方案
  15. 计算机课玩游戏检讨500字,电脑课玩游戏的检讨书
  16. SEO人员应该突破的5大思想误区
  17. 信息系统集成考试中pv,ev,ac相关概念及运算
  18. 基于简单模型KNN——泰坦尼克号获救分析
  19. 领航未来,2022 世界人工智能大会「元宇宙的数字原生进化」论坛等你来!
  20. 华为 oj java题库_华为OJ题目:刷题

热门文章

  1. 金额转换,精确的元--分,换算
  2. jq click()方法无反应?
  3. springboot 发送邮件问题(阿里云企业邮箱)
  4. 从AWS S3换成阿里云OSS存储所踩的坑
  5. Shell修改IP地址
  6. AcWing2022寒假每日一题(1 月 2 日 ~ 1 月 15 日)
  7. python pdf与图片互转
  8. win10 安装“msi”文件提示 “Windows Installer无法打开此安装程序包。请确认该程序包存在,并且你有权访问它,或者与应用程序供应商联” error 2502 2503
  9. “使用区块链进行安全可信的电子医疗记录共享”外文翻译——2019年4月份
  10. 人工智能已经成为新一轮科技革命和产业变革的重要驱动力量