阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

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:5412611

评论 1 条评论

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

iOS开发面试-如何打破30岁的中年危机

iOSer

ios iOS面试

这个导航网站,是设计师福音!

小炮

导航网站

渗透测试面试问题,内含大量渗透技巧

喀拉峻

网络安全 安全 渗透测试

云原生环境下的日志采集、存储、分析实践

火山引擎开发者社区

云原生 日志

自助共享洗车加盟都有什么条件

共享电单车厂家

自助洗车加盟条件 自助共享洗车加盟

如何在众筹中充分利用区块链技术?

CECBC

驱动现代金融发展的“元宇宙路径”

CECBC

24小时无人自助洗车设备多少钱

共享电单车厂家

自助洗车机价格 24小时无人自助洗车 自助洗车设备多少钱

猛肝《Java权威面试指南(阿里版)》,“金三银四”offer必有你的一份!

Java架构追梦

Java 程序员 java面试 后端开发

小程序生态成为私域基建必选项

Geek-peri

绝艺学会打麻将,腾讯AI Lab提出全新策略优化算法ACH

科技热闻

EMQ 云边协同解决方案在智慧工厂建设中的应用

EMQ映云科技

物联网 IoT 智慧工厂 边云协同 emq

低成本、快速造测试数据,这个造数工具我后悔推荐晚了!

Liam

测试 Postman 自动化测试 测试工具 测试自动化

数字经济多项技术突围 元宇宙被赋予更多想象

CECBC

这两个实用的导航网站,推荐给你!

小炮

导航网站

智能家居新浪潮 物联网潜力无限

Geek-peri

小程序 物联网 智能家居

免费ETL批量调度,数据仓库运维工具TASKCTL 8.0 环境使用安装

TASKCTL

大数据 DevOps 敏捷开发 ETL 自动化运维

国产GPU芯片概述

Finovy Cloud

人工智能 GPU服务器 GPU算力

物联网+车载小程序进入发展快车道

Geek-peri

小程序 车联网 物联网

电子版产品手册如何制作?简单的方法来了

小炮

产品宣传手册

实时云渲染有哪些优势?

3DCAT实时渲染

实时云渲染

共建开源组件生态 2022 OpenHarmony组件大赛等你来

科技汇

FastDFS 海量小文件存储解决之道

vivo互联网技术

fastdfs 数据存储 分布式,

自助洗车怎么加盟?加盟流程介绍

共享电单车厂家

自助洗车加盟 自助洗车怎么加盟 自助洗车加盟流程

24小时智能洗车机多少钱一台

共享电单车厂家

自助洗车机价格 24小时智能洗车机 智能洗车机多少钱

超全MySQL笔记整理(面试题+笔记+思维导图),面试再也不怕被MySQL难倒了

Java架构追梦

Java java面试 后端开发

啃完阿里工程师的Java面试八股文,斩获腾讯等6家大厂offer!

Java架构追梦

Java 后端开发 Java八股文

一起看看自助洗车机投放场地怎么选

共享电单车厂家

自助洗车加盟 自助洗车机投放 自助洗车场地

暴打力扣:王者级《数据结构与算法笔记》,一路绿灯进字节Java岗

Java架构追梦

Java 算法 java面试 后端开发

SIG 直播:如何使用 SMC-R 透明加速 TCP 应用? | 第15期

OpenAnolis小助手

TCP 龙蜥大讲堂 SMC-R SIG双周会

Laxcus 6.0正式发布,启航国产化分布式操作系统新征程

LAXCUS分布式操作系统

数据库 大数据 分布式 操作系统 集群

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