AICon上海|与字节、阿里、腾讯等企业共同探索Agent 时代的落地应用 了解详情
写点什么

DDD:架构思想的旧瓶新酒

  • 2019-12-18
  • 本文字数:3502 字

    阅读完需:约 11 分钟

DDD:架构思想的旧瓶新酒

DDD和 DSL、DCI 的关系是什么?开发团队为何需要 DDD?它与微服务与中台又有着怎样的联系?目前业界实践 DDD 最大的问题是什么?11 月 30 日,在由 ThoughtWorks 举办的领域驱动设计峰会 DDD-China 2019上,InfoQ 记者带着这些问题对中兴通讯资深软件架构师张晓龙进行了采访。

DDD、DSL 和 DCI

DDD 概念最早提出于 2004 年,作为一种软件开发的指导思想,DDD 对软件开发带来了诸多可能与方向,张晓龙认为 DDD 为软件开发带来的好处主要有以下几点:


  • 首先,最大好处就是所有参与者围绕一个统一一致的领域模型工作,传统的分析模型和设计模型不再割裂,不管是做设计、做分析还是写代码、写文档,脑海中所构建的画面都是一致的。

  • 第二,DDD 是一个软件开发过程,它显式地把领域和设计放到了软件开发的核心,软件人员和业务人员被受到同样的重视,他们合作来构建领域模型,使得软件的交付质量更高且维护成本更低;

  • 第三,DDD 提出的分层架构,有效分离了业务复杂度和技术复杂度,凸显了领域模型,使得领域层的代码和领域模型保持高度一致;

  • 第四,统一语言非常重要,每个概念在各自的上下文中是清晰的无歧义的,同时要控制领域模型的复杂度,于是 DDD 在战略上提出了分离子域(问题域空间)和拆分 BC(解决方案空间)的模式,BC 间通过 Context Mapping 来集成;

  • 第五,DDD 在战术层面提出了很多模式(聚合,实体,值对象,服务,工厂,仓储),对领域模型中的元素进行了分类,并给出了每类元素在领域模型中的职责和特征,降低了领域模型的构建成本。


张晓龙此前曾在 DDD-China 峰会和ArchSummit全球架构师峰会上分别做过《当 DDD 遇上 DSL(Domain-Specific Language)》、《当 DDD 遇上 DCI(Data,Context, Interactive)》的演讲,在他看来,DDD 和 DSL、DCI 之间存在极强的关联性。


DDD 和 DSL 的融合有三点:


  1. 面向领域;

  2. 模型的组装方式;

  3. 分层架构演进。


DSL 可以看作是在领域模型之上的一层外壳,可以显著增强领域模型的能力。它的价值主要有两个,一是提升了开发人员的生产力,二是增进了开发人员与领域专家的沟通。举个例子:想让 BA 负责流程契约的设计,该流程契约是一个活文档,可以跑测试,而 BA 不熟悉宿主语言。于是,我们设计了一种外部 DSL 来专门描述流程契约,对 BA 非常友好,学习成本也很低(不超过 5 分钟就可以学会),最后发现 BA 很快就广泛使用了起来。外部 DSL 并不一定要定义新文法,我们直接复用了 plantUML 文法,安装该插件可以自动生成序列图,非常棒!对于外部 DSL,需要自己实现一个解析器将 DSL 文法解析成语法树,再根据语法树生成语义模型。语义模型可以看作领域模型(严格的讲语义模型是领域模型的子集),外部 DSL 就是对领域模型的一种组装方式。


DCI 的作用主要体现在两方面:


首先,DCI 助力 DDD 战术设计:


  1. 显式地对 ROLE 建模,解决了贫血模型与充血模型之争;

  2. 一个聚合可以支持哪些 ROLE,一个 ROLE 可以由哪些聚合扮演,一个场景下哪些聚合要扮演哪些角色;

  3. 当 Aggregate 内部实体行为比较多时可以嵌套使用 DCI 来拆分和组合;


其次,DCI 助力 DDD 代码落地:


  1. 对象就是 Data,Client 为 Context,对象在 Client 中的行为就是 ROLE。

  2. 根据正交设计原则得到小类(素材库),根据多重继承(only C++)或依赖注入来组合素材,不管是行为类还是数据类,都按 Role 的方式来组合,对像仅仅组合 Role 并注入依赖;

  3. 小类大对象:类作为一种模块化手段,遵循高内聚,低耦合,让软件易于应对变化;对象作为一种领域对象的的直接映射,解决了过多的类带来的可理解性问题,让领域可以指导设计,设计真正反映领域;领域对象需要真正意义上的生命周期管理。


张晓龙认为,DCI 对一些开发人员的影响可能比 DDD 和 DSL 还大,因为开发人员每天都在不断倒腾代码,想让代码的组合性更强,以便快速应对需求的变化。

开发团队真的需要 DDD

DDD 思想贯穿了整个软件开发的生命周期,包括对需求的分析、建模、架构、设计,和最终的代码实现,甚至对代码的测试与重构。代码是业务的核心资产,不管是否特性团队,开发团队肯定是代码的编写者和守护者。


对于开发团队而言,需要关注以下几点:


  • 首先是统一语言,让团队成员可以做到无障碍的沟通,不管是什么角色都能基于同样的画面进行讨论;

  • 其次是团队中各个角色都围绕领域模型开展工作;

  • 第三是代码物理设计容易标准化,比如说在分层设计时,基础设施层怎么设计,应用层怎么设计,DTO 应该放在哪儿,领域层中各个建模元素如何组织?


更进一步,在分层架构里,应用层更加关注横切面的东西,比如说要上报一个告警,要给用户发送一个 Email,这些最好都集中放到应用层里面。但触发是在领域层发生的,应用层怎么知道?通过领域事件来实现依赖反转,即应用层订阅领域事件,领域层发布领域事件。


在中兴通讯,核心业务属于通信行业,DDD 的应用场景跟互联网企业有着很大差别:


  1. 嵌入式软件;

  2. 兼业务复杂性和技术复杂性;

  3. 软件规模大,功能复杂,特性交叉;

  4. 高质量,高性能,高可靠等要求。


张晓龙举例提到,中兴通讯在开发团队中实践 DDD 的经验具体而言有以下几点:


  1. 领域专家下团队,和团队一起交流和协作;

  2. 教练指导,开展战训营,定期 review;

  3. 架构、设计、编码和工程实践:(1)DCI,DSL,正交设计,组合式设计;(2)编码规范和纪律;(3)嵌入式 C/C++最佳实践;(4)软件工程能力:开发者测试,小步安全流畅的重构,持续交付流水线,每日 Code Review。

DDD 与微服务

DDD 概念提出距今已经有 15 年的历史,前十年时间都一直处于不温不火的状态,而在最近几年才开始大行其道。张晓龙表示,中兴通讯在 2012-2015 年期间也有过一些成功的案例,但对于整个业界来说了解的人并不多。他拿 DDD-China 峰会举例解释:这次峰会的参会者有 500 人的规模,而我们假设峰会在 2015 年之前举办的话,估计参会者不会超过 100 人。因此,我们可以断定是微服务的热风让人们重新发现了领域驱动设计的价值。


微服务架构从提出以来一直没有很好的理论支撑如何合理地划分服务边界,人们常常为服务要划分多大而争吵不休。而 DDD 被发现恰好可以弥补微服务的营养不良:(1)服务最大不要大过一个 BC,否则服务内可能会存在有歧义的领域概念;(2)服务最小不要小过一个聚合,否则会引入分布式事务的复杂度;(3)服务间最好通过 Domain Event 来进行交互,这样可以让服务保持松耦合。微服务和 DDD 的结合,让微服务架构看起来似乎更加稳健了。


“微服务就像是 DDD 的心上人,使得 DDD 真正焕发起了青春。”张晓龙这样解释。


对于业界目前流行的中台概念,张晓龙同样也有自己的看法:


中台和 DDD 不是同一个层面的东西,不能为了把它们联系在一起,而强行找相似点。中台实际上就是多条业务线的共同需求,比如对于滴滴公司来说,快车、专车和出租车等业务都是微服务架构,这些业务的很多服务是相似的,考虑将这些服务从各个前台下沉到统一的平台,这个平台就是中台。中台要考虑各个前台的需求,所以复杂性变高了。


中台是一种企业级的架构模式,从企业全局整体视角来看架构全貌,而 DDD 是一种主流的软件开发方法,用来应对软件的核心复杂性。中台架构可以看作是微服务架构的延伸和发展,服务复杂性很高,所以更需要用 DDD 的方式去设计和建模,但二者之间并不是相同层面的概念。

DDD 的困局

最近几年 DDD 的火爆也给业界开发团队带来了一些迷思,为什么我的 DDD 推行不下去?为什么我的 DDD 做起来总是跟敏捷一样,最后都变了味?


张晓龙总结了 DDD 目前面临的几大困局:


  • 首先是领域案例面比较窄。目前业界的 DDD 实践案例并不多,而且很多案例是偏向互联网领域的,对于工业领域、嵌入式领域和操作系统领域基本没有涉及;

  • 第二,DDD 书籍非常少,而且大多数书籍是以 Java 或 C#写的。如果开发团队用的是 C、C++、Python 或 Go 语言,基本没有可参考的书籍,难度也就更大一些(尤其是 C 和 C++);

  • 第三,各个巨头公司,比如 Google,微软,BAT 等,很少组织、参与或赞助 DDD 峰会,没有形成引导作用,业界自然也就少有跟随效应;

  • 第四,开发团队要么找不到领域专家,要么领域专家无法与开发团队长时间保持沟通,导致实践中出现偏差;

  • 第五,DDD 落地有一定的门槛,对开发者的技能和素质都有较高的要求。


针对以上几大困局,张晓龙也给出了自己的解决方案:


  1. 培训 OOA、OOD 和 OOP 的基本知识,并实战演练,不断弥补与高手的 gap ;

  2. 领域专家和团队一起工作,确保大家头脑中的画面是一致的;

  3. DDD 建模要有文档交付物,并和代码同步演进,以便对代码不熟悉的人员也能看到并理解领域驱动设计成果的全貌。


软件开发没有银弹,DDD 也不是万能的。如果开发团队真的决定用 DDD 的思想指导软件开发,就一定要跟随时代的脚步,吃透 DDD 这个旧瓶里装的新酒。


2019-12-18 16:5412957

评论 1 条评论

发布
用户头像
DDD的分析用于公司的中台构建
2019-12-31 11:04
回复
没有更多了
发现更多内容

库存管理系统到底有什么作用?

低代码小观

CRM 企业管理系统 ERP 库存 CRM系统

架构训练营-模块一作业

伊静西蒙

新思科技推动DevSecOps落地,帮助企业走出“安全孤岛”

InfoQ_434670063458

DevSecOps 新思科技 软件安全

WePack —— 助力企业渐进式 DevOps 转型

CODING DevOps

统一管理 WePack 制品管理 研发构建产物 安全管控

和12岁小同志搞创客开发:手撕代码,做一款温湿度检测器

不脱发的程序猿

少儿编程 智能硬件 温度传感器 创客开发 Arduino

和12岁小同志搞创客开发:手撕代码,做一款密室自动门

不脱发的程序猿

少儿编程 传感器 智能硬件 创客开发 Arduino

华为云联合HarmonyOS重磅发布智联生活行业加速器

华为云开发者联盟

华为云 智联生活

大湾区的“科创土壤学”

脑极体

浅谈MySQL中的游标

麦洛

MySQL 游标

MySQL锁的分析实战

卢卡多多

28天写作 MySQL 数据库 锁分析 签约计划第二季 12月日更

ReactiveNetwork库时如何实现网络状态监听的

Changing Lin

12月日更

如何避免产品Backlog的这七个常见错误

爱吃鱼的小雨

Scrum 敏捷开发 研发管理 需求管理 内容合集

五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

咔咔

MySQL MySQL高级 索引选择而

低代码实现探索(七)赋能产品架构如何做定制化

零道云-混合式低代码平台

2022年,RPA的5大发展趋势

金小K

区块链 AI RPA 机器人流程自动化 人工智能「

开源demo| 智慧协同让企业更便利

anyRTC开发者

音视频 智慧协同 开源demo 远程协助 远程勘查

Android C++系列:Linux网络(一)网络模型

轻口味

android 28天写作 12月日更

作业1

施正威

以容器的方式运行极狐GitLab Runner

极狐GitLab

Docker runner 极狐GitLab

消费医疗门诊的数字化运营

boshi

随笔杂谈

手把手教你实现网页端社交应用中的@人功能:技术原理、代码示例等

JackJiang

即时通讯 IM web socket

年后跑路第一战,从Java泛型学起!

麦洛

Java Java泛型

说说个人影响力

张老蔫

28天写作

基于云的技术架构设计实践-第4篇

hackstoic

运维 云原生 签约计划第二季 业务运维

你知道敏捷团队的迭代目标达成率该是多少吗?

爱吃鱼的小雨

Scrum 敏捷开发 研发管理 内容合集 迭代管理

国产分布式数据库StarDB核心技术大揭秘二:智能运维管控

京东科技开发者

数据库

MySQL性能测试之insert&delete【FunTester框架】

FunTester

MySQL 性能测试 测试框架 FunTester delete

Camtasia混音教程

淋雨

Camtasia

WAVE SUMMIT+2021为开发者准备的“小心思”,你get到了吗

科技热闻

国产分布式数据库StarDB核心技术大揭秘 一:内核分解之数据分片

京东科技开发者

数据库

Python Qt GUI设计:如何调整组件布局比例?(拓展篇—1)

不脱发的程序猿

Python PyQt GUI设计 上位机 调整组件布局比例

DDD:架构思想的旧瓶新酒_架构_小智_InfoQ精选文章