全文4500字,预计阅读时间12分钟。

导读

前面两篇DDD系列文章第1篇:初识DDDDDD系列文章第2篇:建立DDD的知识体系属于了解基本概念的理论部分,从本篇开始进入更为关键的DDD实践部分。本篇主要回答在项目里实施落地DDD首先需要考虑的几件事,比如我的项目适合实施DDD吗,什么时机合适,有哪些实施步骤,怎么衡量实施效果等等。

01

你的项目适合DDD吗?

和很多人聊过DDD,大多数人都有同样的一些疑问,我所在的项目适合DDD吗?如何让项目里其他同事也认可需要实施DDD?要回答这些问题我建议回到你的项目中去,从业务、设计质量、组织三个角度分析一下项目现状。

1.1 是个什么样的业务?

业务维度就一句话,具有一定复杂度的项目才适合DDD。如何看复杂度?从业务流程分支,涉及的业务概念/对象,业务规则的量大致能看出来。另外也可以参考其他复杂行业和场景,典型的复杂业务比如:

  • 电商业务,需要跟商品和钱打交道,商品延伸出优惠券等营销类场景,库存发货场景、供应链场景等等。

  • ERP业务,具有一定规模的企业其日常运营相关的市场、销售、生产、采购、财务等相关系统都很复杂

  • 企业SaaS业务,比如在线办公、营销、CRM、HR、财务等

  • 金融信贷业务,需要连接很多外部资金相关机构,一次信贷过程涉及的流程很长,光风控方向就够复杂了。

  • 保险理赔业务,一份保单的生命周期不比一次电商购物简单,涉及很多流程。

业务复杂度的判断没有标准答案,要不说经验有时候很重要。得着眼你所在项目的核心业务的复杂度,即便要实施DDD也应该把精力放在核心业务上。

同时也可以适当关注一下业务是否有变复杂的趋势,有时候业务目前规模还不大但发展很快的时候,适当做些提前量工作也是有必要的。根据AKF扩展立方体来看,单纯是X轴的流量和Z轴的数据方面增长不会给系统带来太多额外的业务复杂度,应多关注Y轴的功能性需求的演变。

1.2 代码的设计质量怎么样?

相对而言,设计质量的好坏比业务是否复杂更好衡量。可以从架构合理性、代码质量和开发工时得出设计的质量概况。项目里研发的bug多或是产研需求交付工时长往往是因为存在设计上的坏味道,常见的设计坏味道和表现现象有:

设计坏味道

表现现象

模块边界不清:数据修改不通过接口,模块间依赖不合理

发散式修改(一个需求要改多个模块)

散弹式修改(很多需求都要改同一个模块)

调用链路过长

接口设计不正交:接口职责混乱,功能没有做到不重不漏

接口数量膨胀、发散式修改、散弹式修改、接口测试性不强

后端逻辑不纯粹:涉及很多前端展示定制逻辑如字段个数和格式等组合和裁减

接口数量膨胀

架构没有扩展性:对共性和个性的功能没有分类设计

修改频繁

概念失配:业务概念命名混乱,业务对象的数据和行为分离

过程式代码多、重复代码多

关注点没有分离,依赖不合理

代码测试性不强

1.3 是个什么样的组织?

  • 一看组织文化:一个组织呈现出来的样子取决于组织的文化,比如是否对技术先进性有追求、对做事方法追求精益求精。产品团队和研发团队是否有足够的信任,比如有共同的业务愿景,彼此理解对方的工作,不会抱怨对方不给力、拖后腿等。

  • 二看负责人:一个典型的产研发团队往往有总负责人(俗称为业务1号位)、产品负责人(俗称为产品1号位)和研发负责人(俗称为研发1号位)。这几个人对产研团队的组织文化影响最大,甚至可以说这几个人对DDD的认知程度决定了整个组织是否会实施DDD的决心和后续实施的效果。

  • 三看骨干成员:组织里的骨干成员起到很重要的承上启下作用,对战术的落地质量起关键作用。需要有实施DDD的方法和经验。

1.4 小结

以笔者亲身经历来说,大多数项目在业务复杂度和设计坏味道方面都能找到印证,但在组织这个维度不太容易推行DDD。因此不管你是组织里的架构师、研发还是产品,如果要想在项目里实施DDD,需要先跟几位负责人解释清楚必要性和意义。阐述清楚业界的大趋势是流量红利已过,很多领域都需要开始比拼精耕细作的基本功了。其实很多产研团队的负责人也有诉求如何提高团队整体作战能力,如何加快产研交付产品功能的速度,如何让团队成员有技术发展空间等等。答案不止DDD,但DDD能帮上一些忙。

02

什么时机开始实施DDD?

我们常说种一棵树的最佳时机是十年前,其次是今天。在项目里实施DDD也需要抓住时机。结合上面讲的业务、设计、组织三个维度看该抓住哪些时机。

2.1 业务变化时

业务变化往往来自上层的战略变化,比如原来非核心业务变成核心业务了,原来核心的业务需要加速扩张,结果就是资源投入更多了。这时候的主要矛盾大概率是要快速完成业务指标,因此需求功能开发的效率是技术团队的首要目标。但是在技术落地方面不仅仅只是增加研发人员数量这种方法,很多时候需要同时考虑技术架构的演进,研发人员的专业素质的提高。因此业务变化更多的是带来了资源投入和上层的关注度,如何接受住挑战,往往需要通盘看技术问题的解决之道。毕竟技术在短期内是会被高估的,但长期看又会被低估。

2.2 技术架构变化时

技术架构变化伴随着技术重构,一般什么时候会在项目里提起技术重构呢?质量问题变得迫在眉睫的时候。结合上面提到的那些设计坏味道,如果产品的功能缺陷多,较长一段时间内有很多客户反馈,或者是需求开发周期过长,远低于预期,都可能是技术重构的时候了。大家提到技术重构经常想到的是代码重构、纯技术架构调整,但一个架构好不好需要先理解透彻业务。如何理解业务并和技术实现保持紧密联系?这就可以考虑结合DDD来做技术重构,架构和代码不会腐烂过快,效果会更保鲜。

2.3 组织变化时

组织变化经常伴随团队职责范围的变化,也意味着功能模块和人员的交接。组织的合并拆分,需要审视对应的系统要不要关停并转。知名的康威定律就说,系统架构和组织架构会趋于一致,现实中可能是因为组织变了系统架构跟着变,也可能是系统架构变了要调整组织架构。但两者的适配和组织效率是直接相关的。因此组织变化带来的模块合并拆分也是实施DDD的一个好时机。

03

实施DDD要遵循哪些步骤,产出什么?

了解DDD的实施步骤需要结合着传统的软件开发过程来看,不管是敏捷开发还是精益开发,测试驱动还是DDD等开发模式,总离不开软件开发的这些必要阶段(规划、分析、设计、实现、运维)。只是每种开发模式的侧重点不同,解决的主要矛盾不同而已。以下表格给出DDD各阶段的任务、人员和产出,作为参考。

传统开发模式-各阶段

DDD各阶段

DDD-任务

DDD-参与人员

DDD-产出

规划(问题定义、可行性研究)

<可选>

  • 按照常规的步骤理清业务场景和流程,为战略设计做好准备

  • 领域专家

  • 产品经理

  • 架构师

  • 产品愿景、理念

  • 业务场景划分图

分析(需求分析)

战略设计

  • 领域识别和划分

  • 限界上下文识别和划分

  • 统一语言建立

  • 领域专家

  • 产品经理

  • 架构师

  • 研发骨干

  • 领域划分图

  • 限界上下文划分图

  • 映射关系图

  • 统一语言

设计(概要和详细)

战略&战术设计

  • 领域模型设计

  • 统一语言完善

  • 领域专家

  • 产品

  • 架构师

  • 研发

  • 各限界上下文内领域模型图

  • 领域/业务接口图

实现(编码和测试)

技术实现(代码架构、代码规范)

  • 分层架构

  • 代码骨架

  • 架构师

  • 研发

  • 分层架构图

  • 代码骨架

运维

技术实现(工具)

  • 代码骨架脚手架

  • 规范检查工具

  • 研发

  • 自动生成代码骨架工具

  • 规范检查工具

另外要提的一点是不同的项目现状,不一定都需要经历上述的完整步骤。应该因地制宜地做出选择,比如下面列举几种不同的项目可以按需裁减:

  • 新的业务项目,开始时没有什么领域专家和架构师,就是几个产品经理和研发。建议多花点时间在规划、分析和设计阶段,把核心领域的主要业务场景拆解清楚,划分好主要上下文的边界,识别出主要的领域概念并建立双方沟通的统一语言。争取做到核心领域写的代码不会给将来的演进带来欠债和负担。

  • 存量项目,但其开发效率日益下降,需要启动技术主导的技术重构。建议多花点时间在分析和设计阶段,把限界上下文和相互关系划分清楚。技术实现要往前一步,争取和业务设计绑定起来的关键。

  • 中大型业务项目(注:50+人员参与的项目足够称为中型规模),想往中台类业务演进。建议应该经历上述完整步骤。

  • 战略调整,启动的中大型业务项目。建议应该经历上述完整步骤。

04

如何衡量DDD的实施效果**?**

一种技术方法的效果度量一直是业界挺重要但也挺难回答的问题。比如如何衡量研发人员的研发质量?看bug数量吗?看千行代码bug率吗?都有一定局限性,毕竟少做少错是不少人的生存法则。回到生活当中,你会如何衡量家长给小孩请补课老师的效果?看期末考试成绩?听授课老师的评价?估计都有局限性,毕竟小孩自己的悟性也在自然提高,这效果的部分没法刨去。但是这些都不是不做度量的借口,下面从几个维度试图给出实施DDD的效果衡量方法。前提是前面提到的项目实施条件和时机成立的情况下。DDD解决的主要矛盾是控制业务复杂度,因此效果主要围绕组织里的人面对复杂度变高时的执行效率。

组织效率

  • 组织资源是否集中在了核心业务领域

  • 是否能用统一语言沟通描述业务,表现在需求评审、站会等有关会议的效率上

  • 领域知识是否得到沉淀,是否有人能承担『领域专家』

  • 团队间职责模糊地带少,相互扯皮的机会少

开发效率

  • 模块粒度是否合适、模块间依赖是否健康

  • 接口数量是否稳定,不膨胀

  • 因为功能理解不足引起的bug数量是否低

  • 模块和接口的自测性程度高不高

  • 代码可读性,人员交接和新人上手是否足够快

05

FAQ(常见问题)

问题1:没有大规模投入的业务值得做DDD吗?

答案1:如果没有后续资源投入的话就看维护当前业务的运转投入的资源大不大,大的话再看是否符合实施条件

问题2:前端项目值得做DDD吗?

A:业务逻辑不是前端项目的主要矛盾,前端项目多针对页面相关概念进行代码组织,业务逻辑多下沉到后端,因此业界也比较少见在前端实施DDD。前端有几个方向比如如何建设组件化(对复用部分如何抽象)、BFF层建设(后续文章会讲到)、业务对象的命名统一等需要和后端DDD实施联动起来。

问题3:用什么开发语言的项目适合DDD?

DDD和语言无关,其实业务复杂的项目立项时就对开发语言做过一次筛选了。实际情况java、c++、golang这些静态语言相关的项目实施DDD的更多。

问题4:如何说服老板实施DDD?

A:参见上面章节1.3和1.4

问题5:产品团队不参与,怎么实施DDD?

答案在于组织里的领域专家在哪?实施DDD需要领域专家才能把正确的业务逻辑梳理和提炼出来。领域专家不是专职,简单说懂业务的就是领域专家,有时候可能需要拼凑好几个人的知识。很多情况下产品团队比技术团队更懂业务,再者后续业务迭代演进少不了产品经理的参与。因此需要产品团队的参与,但技术团队可以主导实施DDD,不矛盾。

问题6:实施效果不好衡量,怎么办?

参见上面章节4,应该从项目当前的主要矛盾出发找到衡量办法,哪怕不是很严谨。

06

结语

你的项目从哪里来?现在在哪?要去向哪里?值得多花点时间在实施DDD前想清楚这些问题,正所谓心中有地图到哪都是路。后续章节将带你沿着地图开启实践之旅。

感谢阅读,往期文章节选:

DDD系列文章第1篇:初识DDD

DDD系列文章第2篇:建立DDD的知识体系