写点什么

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

评论 1 条评论

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

PostgreSQL 15新版本特性解读(含直播问答、PPT资料汇总)

墨天轮

数据库 postgresql

直播app运营模式有哪几种,我们该选择什么样的模式?

开源直播系统源码

软件开发 直播源码 带货直播

一场分销裂变活动,不止是发发朋友圈这么简单!

CRMEB

Pisa-Proxy 之 SQL 解析实践

SphereEx

数据库 SQL语句 SphereEx

NFT双币质押流动性挖矿dapp合约定制

开发微hkkf5566

【ELT.ZIP】OpenHarmony啃论文俱乐部—数据密集型应用内存压缩

ELT.ZIP

OpenHarmony 压缩数据 压缩算法 ELT.ZIP

【ELT.ZIP】OpenHarmony啃论文俱乐部—见证文件压缩系统EROFS

ELT.ZIP

OpenHarmony 压缩数据 压缩算法 ELT.ZIP

字节跳动埋点数据流建设与治理实践

字节跳动数据平台

字节跳动 数据治理 数据流 埋点治理 数据研发

等保2.0密码要求是什么?法律依据有哪些?

行云管家

网络安全 等保 等保2.0

基于 Nebula Graph 构建百亿关系知识图谱实践

NebulaGraph

知识图谱 Nebula Graph

2022年中国音频市场年度综合分析

易观分析

音频市场

Vue3 - $attrs 的几种用法(1个或多个根元素、Options API 和 Composition API)

德育处主任

Vue composition-api 组件通信 6月月更 Vue透传

C#/VB.NET 使用插件将HTML转为PDF

在下毛毛雨

C# html .net PDF

易周金融 | Q1手机银行活跃用户规模6.5亿;理财子公司布局新兴领域

易观分析

金融 手机银行

好用到爆!GitHub 星标 32.5k+的命令行软件管理神器,功能真心强大!

沉默王二

Java macos GitHub

国内首家!EMQ加入亚马逊云科技“初创加速-全球合作伙伴网络计划”

EMQ映云科技

物联网 IoT emq 亚马逊 6月月更

开源二三事|ShardingSphere 与 Database Mesh 之间不得不说的那些事

SphereEx

数据库 SphereEx Apache ShardingSphere Database Mesh Pisanix

如何使用物联网低代码平台进行画面管理?

AIRIOT

低代码 物联网 低代码开发 低代码开发平台 低代码,项目开发

熊市慢慢,Bit.Store提供稳定Staking产品助你穿越牛熊

股市老人

DevOps 如何帮助前端提升研发效率?

SoFlu-JavaAI开发助手

等保三级密码复杂度是多少?多久更换一次?

行云管家

堡垒机 等级保护 过等保 等保2.0

鸿蒙发力!HDD杭州站·线下沙龙邀您共建生态

最新动态

Hi,你有一份Code Review攻略待查收!

Jianmu

后端 Code Review 代码规范 SonarQube checkstyle

【干货分享】红黑树硬核讲解

C++后台开发

后端开发 红黑树 linux开发 Linux内核 C++开发

如何制作登录界面

海瞳Seapupil

OpenSSF 安全计划:SBOM 将驱动软件供应链安全

SEAL安全

软件物料清单

什么是 ICMP ?ping和ICMP之间有啥关系?

wljslmz

网络协议 ping ICMP 6月月更

巧用redis实现点赞功能,它不比mysql香吗?

阿Q说代码

MySQL 数据库 redis 点赞

海量数据!秒级分析!Flink+Doris构建实时数仓方案

领创集团Advance Intelligence Group

数据 Doris flink sql 平台

Substrate 源码追新导读 4月第2周技术更新: 以太坊地址转换, BEEFY协议等

彭亚伦

rust Substrate 波卡生态

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