DDD如何落地:去哪儿的DDD架构实操之路

发布时间 2023-11-14 15:28:12作者: 疯狂创客圈

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 :

免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备
免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,完成职业升级, 薪酬猛涨!加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷1)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷2)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷3)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领

免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取


DDD如何落地:去哪儿的DDD架构实操之路

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

谈谈你的DDD落地经验?

谈谈你对DDD的理解?

如何保证RPC代码不会腐烂,升级能力强?

微服务如何拆分?

微服务爆炸,如何解决?

你们的项目,DDD是怎么落地实操的?

所以,这里尼恩给大家做一下系统化、体系化的梳理,使得大家可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”

也一并把这个题目以及参考答案,收入咱们的 《尼恩Java面试宝典PDF》V123版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,后台回复:领电子书

除了本文,尼恩输出了一个 《从0到1,带大家精通DDD》系列,帮助大家彻底掌握DDD,链接地址是:

阿里DDD大佬:从0到1,带大家精通DDD

阿里大佬:DDD 落地两大步骤,以及Repository核心模式

阿里大佬:DDD 领域层,该如何设计?

极兔面试:微服务爆炸,如何解决?Uber 是怎么解决2200个微服务爆炸的?

阿里大佬:DDD中Interface层、Application层的设计规范

字节面试:请说一下DDD的流程,用电商系统为场景

大家可以先看前面的文章,再来看本篇,效果更佳。

另外,尼恩会结合一个工业级的DDD实操项目,在第34章视频《DDD的顶奢面经》中,给大家彻底介绍一下DDD的实操、COLA 框架、DDD的面试题。

本文目录

去哪儿网 DDD架构实操之路

作者介绍

李全党,2021 年加入去哪儿网,担任酒店供应链代理商和基础信息业务负责人、业务架构SIG成员,拥有 10 年以上系统研发和软件架构设计经验主导搭建多个 DDD 项目,有高并发、分布式服务、高可用的建设优化经验。

朱浩曼,2021年9月加入去哪儿网,担任标准代理商业务负责人、业务架构SIG成员。

分享概要

一、架构设计理念与技术

二、业务系统重构背景

三、系统重构改造模式和架构选择

四、业务驱动的微服务架构演进实践

五、总结和思考

六、Q&A

一、架构设计理念与技术

1. 架构演变路径

  • 单体(又称巨石系统):将所有业务集成在一个系统中。在项目的早期阶段,企业通常会选择单体架构以降低运营等成本。
  • 服务化:随着业务的快速发展和流量增长,进入服务化阶段。这个阶段包括服务拆分、治理和模型抽象。
  • 平台化:在业务膨胀期过后,服务化维护成本上升,服务粒度过于细分,重复开发等问题暴露,因此走向平台化(服务能力积累、服务整合、领域自治等)。
  • 中台化:构建企业级能力复用平台,是平台化的下一步,具备数据互通能力和业务变化高响应力。

这种业务架构的演变路径,从侧面反映了互联网企业的演变路径。每种架构的好坏并非绝对,选择与否,仅取决于是否适应当前和可预见的未来。

本次分享主要介绍服务化到平台化的过程,即从服务细粒度到领域能力积累的演进过程。

2. 架构设计理念

以业务为中心、适应业务变化是架构设计成功的关键。指导业务架构设计的维度包括:

1)商业模式及成熟度

传统行业的业务相对稳定和成熟,非必要情况下建议构建单一服务。如需拆分,建议将变化频繁和不频繁的业务拆分。

互联网行业分为初创公司和成熟稳定的公司:

  • 初创、商业不稳定的公司:需要多种业务快速试错,可采用微服务。通过微小的单体服务器,快速构建探索场景,以技术的确定性应对未来发展的不确定性。例如,去哪儿网的某些团队在制定简单方案后,可使用微服务获取市场反馈,快速验证效果。

  • 商业稳定或固化的公司:不再需要技术端的灵活性,也不愿承担灵活性带来的架构维护成本,此时可以考虑合并微服务,以降低运营成本。

目前旅游行业已相对稳定,去哪儿网符合上述第二种情况,可以考虑将之前拆分过细的微服务进行合并。这也是去哪儿网架构演进的原因之一,原有业务拆分过细,达到人均10个应用,维护成本极高。

2)面向业务的变化

  • 组件设计围绕业务变化
  • 组件调用非强依赖
  • 组件业务复用
  • 组件颗粒度与成熟度

为快速适应业务变化,需识别业务核心问题,明确业务边界,实现业务组件的最大化复用;区分变化与不变的业务,将变化限制在一定范围内,从而降低影响。

面向业务变化与不变的情况下,组件颗粒度要拆分到什么程度?

组件拆分粒度过细时,可复用性强,但组装复杂;拆分粒度过大时,使用方便,但应用场景有限。

3)技术延迟决策

《架构整洁之道》一书提到:“良好的架构设计应关注用例,并将它们与其他周边因素隔离。”

在前期,应关注用例,后期再决策具体技术。

4)康威和逆康威定律

  • 康威定律:产品的形态无意识地映射了其组织沟通的格局。系统的构建本质上复制了公司的组织架构,而系统各部分之间的接口则展现了公司各部门间的信息传递与合作方式。
  • 逆康威定律:当前组织效率不够高时,可以优先进行系统设计,利用系统设计来逐步优化后的组织架构。例如,去哪儿网在 2021 年实施了内部领域驱动设计,外部 API 的战略,对团队和职责进行了合理划分,这就是逆康威定律的一个实践案例。

5)面向测试、运维

测试是确保系统质量的关键环节,采用测试驱动开发(TDD)来验证架构的合理性、可隔离性和易测试性。

6)软件质量属性

在开发和运行阶段,软件质量特性表现为可用性、可维护性、性能、安全性、易用性等。

以功能性为核心进行架构设计,依据质量特性进行增量式的迭代重构和优化。

上图是架构的一些关键技术,这张图的粒度较粗。

从下往上观察,公司底层主要由容器和自动化技术支持,上层则是监控和治理、前后端分离的系统。

根据这张图,领域驱动设计(DDD)成为整个架构的指导原则。

二、业务系统重构背景

1. 业务介绍:酒店基础信息

上列四张图简单展示了去哪儿网本次重构的主题,也是酒店基础信息部所负责的业务。

  • 列表页:用户打开 APP,输入目的地和入住时间,点击搜索,便会转到列表页,展现搜索地点的所有酒店列表信息。
  • 详情页:点击希望入住的酒店,即可进入详情页。
  • 酒店Info:点击酒店名字,则可进入酒店Info页。
  • 进订页:用户决定预定酒店房间后,就跳转到进订页。

2. 基础信息业务架构

注意:请点击图像以查看清晰的视图!

上图展示了酒店基础信息业务对应的架构。

去哪儿网售卖的酒店,来源于各个代理商和集团分销的信息,按照图示自下到上,经过基础层,然后到达基础信息部门的主要业务层。

业务层最重要的内容是酒店聚合,包括代理商酒店Tree和Q物理酒店。

我们将各个代理商提供的酒店信息,按照一定业务逻辑规则,聚合到去哪儿网的Q侧物理酒店,并将这部分信息对外销售,以优化用户体验。

为什么能够提升用户体验?

举个例子,比如现在投放的是季枫酒店,A代理商将其称为季枫酒店北京店,B代理商将其称为季枫酒店北京中关村店,C代理商称之为季枫酒店北京中关村苏州街店,用户容易混淆。

因此,去哪儿网将各代理商提供的酒店信息,按照一定的业务逻辑、规则整合为外部可见的唯一物理酒店。

酒店Tree的含义是,每个代理商投放的酒店,对应到去哪儿网的酒店,以去哪儿网的酒店为根,下方挂接不同代理商投放的酒店信息,形成对应关系。

目前,我们团队的核心业务是将基于业务层的酒店信息,提供给应用层,如 APP 搜索或筛选时展示的信息。

3. 落地技术中心战略,偿还技术债务

旅游业可能是受疫情影响最大的行业之一。在此背景下,技术中心在 2022 年提出了“巩固效率之本,分担产品之忧”的战略,从而开启了领域驱动设计(DDD)的重构之旅。

如上图,重构前,业务和业务架构存在以下问题:

  • 数据写入链路长:缺乏核心业务的统一出口,数据更新不够及时。由于没有实时查询能力,其他团队在调用数据时,需要先拉取并自行缓存。
  • 核心业务入侵:产品需求交付效率不高,一个产品需求可能需要对五个微服务进行调整。
  • 核心业务分散:图中灰色条块代表着我们的核心业务,它受到整个链路的耦合影响,分散在各个系统中,导致核心业务遭受侵入。

为了解决这些问题,技术中心决定采用领域驱动设计(DDD)进行系统重构。通过这一方法,我们希望能够提高产品需求交付效率,缩短数据写入链路,以及降低核心业务受到的侵入程度。此外,DDD 还能够帮助我们实现核心业务的模块化,使得各个系统之间的耦合度降低,从而提高整个系统的灵活性和可扩展性。

4. 系统重构模式选择

没有最好的架构,只有最合适的架构。

以下是备选的系统重构模式:

  • 修缮者:在现有系统基础上,新增一层抽象层,确保对外服务能力不变,然后对内部进行优化改造。

  • 绞杀者:修缮没有办法适应现状的情况下,需要另起炉灶,在外部构建新功能,逐步剥离原有逻辑。为新功能提供服务,逐步淘汰或重构各个需下线的服务。在重构过程中,要权衡颠覆者的优缺点。

  • 优点:不影响原有业务,一旦条件成熟,新系统可完全替代旧系统。

  • 缺点:在一段时间内需要维护两套系统,付出额外的开发维护成本。

  • 演进式:对于老项目逻辑模糊的情况,采用演进式迭代。识别老系统中的核心业务逻辑,从最小可行性产品(MVP)版本开始,快速迭代核心业务,率先上线观察效果,然后逐步将剩余的边缘业务切换过来,并及时调整。

  • 优点:控制迭代风险,避免全面替换系统,降低不可预测的影响。

三、系统重构改造模式与架构选择

前文讲解了架构的演变路径、理念及改造模式的选择,最终衍生出来的系统重构框架是什么样子?

系统重构模式选择

以业务为导向,适应业务变化是现代架构设计成功的核心要素,而领域驱动设计(DDD)的理念恰恰符合这一成功架构设计的原则。

1)服务业务战略

站在EA(企业架构)角度(包括业务架构 BA、应用架构 AA、数据架构 DA、技术架构 TA)的角度出发,DDD 能够将业务架构与应用架构相结合,将问题领域与应用架构分离。通过分解业务架构中的“价值流 + 业务能力”,实现能力的下移。同时,根据 DDD 划分的限界上下文和聚合,构建应用架构,实现自下而上的“高内聚、低耦合”。

2)演进式架构

DDD 的核心思想包括:

  • 战略层面:业务问题分析→分解子问题域,识别核心域→分而治之,降低业务复杂度;
  • 战术层面:识别问题域的不同业务上下文→领域建模,定义聚合,组件化业务需求→指导微服务的拆分;
  • 实现层面:利用成熟的分层模式、依赖倒置屏蔽掉技术细节复杂度,通过DDD方法设计的微服务,不仅可以通过限界上下文和聚合实现微服务内外的解耦,同时也可以很容易地实现业务功能积木式模块的重组和更新,从而实现架构演进。

总之,自上而下地拆解业务,并以此为指导,自下而上地构建模型,最终达到高内聚低耦合的状态。

在系统重构过程中,我们选择了绞杀模式和演进模式。鉴于系统复杂度高,了解业务细节的人员较少,为了降低重构对现有业务的影响,我们将核心资源投入到核心业务中,快速上线以观察效果。以下将详细介绍演进实践。

四、以业务驱动的微服务架构演进实践

1. 领域驱动设计过程

上图是以业务驱动的微服务架构演进的实战过程,介绍DDD的完整流程和关键路径。

进行领域驱动设计时,需要对组内成员进行定位。

最重要的是识别领域专家,即那些对特定领域有深入认知的人,他们能帮助团队成员更好地理解业务,有利于后续的头脑风暴和建模过程;其次是技术专家和开发团队。

领域驱动设计的关键路径如下:

第一步,领域专家与开发团队针对具体问题,明确业务愿景,探讨需求,从而确立统一的语言,积累领域知识。统一语言意味着对问题领域内的概念达成共识,例如,团队成员对某个词语的定义有明确的认识,没有歧义,从而降低沟通成本。

第二步,分析问题域并划分子域(比如核心子域、支撑子域、通用子域),进而划分限界上下文,构建上下文地图。

第三步,领域建模并实现模型。将以上两步分析,映射到代码层面,进行模型实现。这一步骤可以概括为“两关联一循环”。“两关联”指的是统一语言与模型之间的关联,以及模型与软件实践之间的关联。“一循环”意味着在实践过程中,可能会遇到各种困难和不确定性,需要在不断迭代的过程中提炼知识,最终趋近于完美的模型。

总之,领域驱动设计是一个动态迭代的过程,通过明确团队成员的角色,发掘领域专家,建立统一语言,分析问题领域,进行建模和实践,不断优化和完善模型。在这个过程中,团队成员需要密切合作,充分发挥各自专长,共同推动领域驱动设计取得成功。

2. 基于DDD落地实践

上图展示了基于DDD落地实践的过程。

首先是定位愿景,其重要性在于决定了后续的发展道路;

其次,分析问题域中的现有业务场景;

然后,根据划分的子域,识别限界上下文;

最后,在限界内进行领域建模和实现模型。

1)问题域分析

① 定位愿景

麦肯锡提出“电梯演讲”概念是指,在乘坐电梯的30秒之内,向顾客清晰准确地解释解决方案,即使用简短的语言精准说明业务价值。

比如,去哪儿网的核心价值是“总有你要的低价”。因此,所有核心工作都应围绕低价展开。落实到基础信息团队,我们的愿景就是提供丰富的信息聚合。

② 明确领域专家

由于产品迭代频繁,系统演进缺乏领域专家。因此,按照产品、QA、技术人员的顺序来确立领域专家。

为了分析原有项目中,哪些用户用例与我们的愿景密切相关,我们整理了用例图,并安排同学逐一分析。

分析结果显示,经过多年的迭代,许多业务已经不再使用,旧业务无法适应现有的商业模式。

因此,我们将这些业务下线或重新分配资源,最终将 188 个用例精简为 79 个,大大简化了工作内容。

③ 事件风暴

事件风暴主要关注三个方面:识别领域事件、识别决策命令、识别领域名词。

事件风暴的输出将作为后续领域建模的输入,需要遵循以下原则:

  • 业务视角事件:从业务视角分析领域事件,例如,某个业务操作产生特定数据,引发业务流程状态变化,并向外发送消息。在进行头脑风暴时,技术人员容易陷入代码细节,而忘记最初的目标。
  • 先发散,再收敛:首先列出所有想法,然后在基础上进行收敛。
  • 决策命令: 分析导致事件发生的人员和动作。

④ 统一语言

没有 DDD 经验的同学可能会问,什么可以作为统一语言?

答案是,什么都可以作为团队的统一语言。

例如,如果一个老系统的内部逻辑复杂且难以理解,重构成本高,不易修改,可以将这部分代码作为团队内部的统一语言。这样一来,产品和技术的同学都了解老系统的目标、能力和应对策略。

由于技术同学在描述事物时偏向于使用代码逻辑,这可能导致与产品同学的沟通出现偏差。

在这种情况下,统一语言可以拉近双方的认知差距。技术同学只需抛出几个领域名词,产品同学就能理解。

需要注意的一点是,统一语言的术语表应包含中英文对照,以便在后期编码和解码过程中,在代码层面实现认知统一。

2)识别限界及子域划分

识别限界上下文的总体原则是先业务后技术,上图展示了领域层面的划分流程。

  • 降低技术复杂度:根据限界上下文承受的流量不同,我们通过创建弹性边界、部署和可用性测试,采用不同方法对待不同的限界上下文。

  • 降低管理复杂度:基于领域层划分的业务边界会影响工作边界的划分。上述提到的康威定律和两个披萨原则(一个高效的技术研发团队,最佳团队规模应控制在能吃两个披萨的人数)都对工作边界具有指导意义。

  • 降低业务复杂度:在业务层面,要消除语言的歧义。例如,在去哪儿网内部,商务和技术团队可能对“酒店”这个词汇的理解有所不同,因此在确定限界上下文时要避免这种情况。

限界上下文的特征

  • 独立进化原则:对外提供稳定接口,内部变化不影响外部。
  • 稳定空间原则:外部变化不会影响自治单元。
  • 自我履约原则:自治单元自行决定职责。例如,在进行代理商酒店数据抓取时,无需进行后续解析。
  • 最小完备原则:自治单位职责完整,无需向其他自治单位求助以获取自身信息。

在绘制上下文依赖地图时,要遵循三不原则:避免双向依赖、循环依赖和过长依赖。

如上右图所示,我们在制作上下文依赖地图时,我们发现酒店解析依赖酒店抓取,酒店抓取依赖酒店聚合信息,酒店聚合信息依赖静态信息,静态信息依赖酒店解析出的数据,形成循环依赖。因此,划分方式不合适。针对这种情况,我们创建了“酒店上下文”环节,打破循环依赖。

在限界上下文后,需要识别核心域、支撑域和通用域,划分参考是与业务愿景的相关性。

识别子域的好处是,对外可以明确告知自身核心竞争力;对内可以明确人员、设备资源分配,评估产品需求优先级以及是否处于核心领域。

3)领域建模

根据事件风暴和限界上下文的输出,我们可以构建领域模型。

① 建模意义

  • 使用聚合表达业务的“高内聚,低耦合”特性;
  • 降低业务复杂度,以便更好地应对业务变化。

② 建模过程

  • 识别实体、值对象、丰富领域逻辑
  • 定义聚合、识别聚合根

在建模过程中,最棘手的问题在于如何把握尺度,也就是判断哪些方法应被纳入模型,哪些属性应置于哪个模型。我个人认为,只要在团队内达成共识,无论实际结果如何,都可以视为正确。因为建模是一个不断优化的过程,随着对业务理解的深入,要推翻之前的结论并一次性构建完美模型较为困难。

在分层架构中,领域层和业务层都应存在。若盲目将功能和用例纳入领域层,可能导致领域层过于庞大,进而影响其可重用性和业务表达力。因此,我们需要正视模型和领域能力的不确定性,逐步采取迭代方式,将能力下沉至领域模型中。

③ 建模原则

  • 重点关注核心域建模:投入核心资源
  • 聚合尽量小,适应业务变化
  • 聚合边界内强一致性
  • 抽象模型,防止过多属性拍平(DP):属性被拍平的弊端是,模型内字段太多,无法识别识别模型。

上图展示了两个原则:共性业务能力优先下沉到领域,共性技术问题抽象成业务。

没有完美的模型,也没有正确的模型,领域模型的共识即为正确。因此,团队的整体能力决定了模型完美程度的上限。提供一个参考的检验技巧:在建立完模型后,可以使用业务场景检验模型的完整度。如此循环往复,模型将逐渐完善。

④ 落地实践时划分微服务

如上所示,业务边界、康威定律、业务变更频率、弹性边界、技术选型等,都可作为划分依据。

需要指出的是,一个微服务可以包含多个限界上下文,但只能包含一种子域类型(核心、通用、支撑),不能将核心域和支持域放在同一微服务中。如果支持域的可用性不佳,可能会影响核心逻辑,因此可能为这个问题付出沉重代价。

4)模型实现

① 业务流程和领域模型映射

如上所示,业务流程或业务用例包含多个阶段,每个阶段又包含一系列活动。我们将这些业务活动与整个分层架构相结合,构建相应的映射关系。

建立映射关系的好处在于,在分层架构和领域模型高度凝聚、完善的情况下,便于后续需求的接入和扩展。从上到下分解业务流程,进行分层映射,技术负责度得以隔离。

② 模型映射代码清单

如上图所示,应用层、领域层、基础设施层是领域对象的聚合,模型映射代码清单明确了每个层次的能力、领域层的领域对象、是否存在前置依赖对象,以及包名、类名和方法名。这些内容与前面提到的中英文对照表相对应。

构建这份代码清单有助于团队内部协作,提高开发效率;为新成员提供参考,快速了解项目核心逻辑和能力。

③ COLA应用架构

在开发阶段,我们采用了 COLA 开源框架,其分层架构包括适配层、领域层、应用层和基础设施层。

无论是 COLA 还是 DDD 的分层架构,都围绕业务核心,基于稳定的领域模型,对外提供领域能力。

选择COLA的原因如下:

  • 定义良好的分层结构、规范;
  • 层内部结构“聚合分包,功能分类”;
  • 提供了实用的应用架构最佳实践:《领域驱动设计》一书主要提供设计思想,而 COLA 则为实际应用提供了可借鉴的模板。

下图是我们内部基于COLA架构落地微服务的实践。

  • Adaptor:多端适配

  • Client:业务提供的接口,比如Dubbo

  • APP:业务用例Case的编排,含executor、publish、qschedule等

  • Domain(聚合、实体、值对象的定义)

    • 业务规则显式化,包括逻辑判断和对象设值代表的含义,纯内存操作;
    • 实体(Entity):解决单个对象的逻辑变更,领域服务解决多对象的业务逻辑变更;
    • 领域服务(Domain Service):处理多个对象的业务逻辑变更;
    • 限制:不允许跨聚合调用;
    • 特点:充血模型
  • Insfrastructure:Repisitory实现;ACL的定义和实现

  • Common:提供公共属性、工具类,由domain调用

通过运用 COLA 框架,我们希望实现业务核心的模块化,提高系统的可扩展性和灵活性。在实际开发过程中,团队成员需遵循分层设计原则,紧密协作,不断积累和共享领域知识,共同推动项目的成功。

上图是对前一张图的具体描述,我们采用了 CQRS 模式,即命令与查询职责分离。

前文的一张图描述了架构重构前的状况:核心业务分散在各个服务中,没有得到收敛和整合,业务耦合度较高。通过限界划分和领域建模,我们实现了业务的分离。

在改造前,系统缺乏实时查询功能,各团队将数据拉回并本地缓存。经过重构,我们采用了异步调用机制,实现了数据持久化,并对外提供查询功能。

在重构前,系统没有提供实时查询能力,各团队将数据拉走并进行本地缓存。重构后,基于异步调用机制,实现了数据持久化,并对外提供查询功能。

④ 领域模型与代码模型映射

上图是领域模型与代码模型的映射。分层对应上一张图展示的架构,在 Domain 层,根据领域划分进行聚合分包。图中标蓝的 Hoteltree 就是前文提到的酒店聚合,在该领域内进行功能划分。

Domain Primitive 是 Value Object 的进阶版,它在原始 VO 的基础上要求每个 DP 拥有概念的整体,而不仅仅是值对象。在 VO 的不可变基础上增加了有效性(Validity)和行为。

DP 特征如下:

  • 拥有完整的概念整体,精准定义
  • 使用业务域中的原生语言
  • 业务域的最小组成部分,可构建复杂合
  • 隐式转显式

例如,联系信息对外显示为电话号码,但背后隐藏了区号、国内外来源等隐式属性。通过 DP,我们可以找出这些隐式属性并将其转化为显式,这是推荐使用 DP 的关键原因之一。

通过以上映射,我们希望实现领域模型的清晰划分,降低业务耦合度,提高系统的可扩展性和灵活性。在实际开发过程中,团队成员应紧密协作,不断积累和共享领域知识,共同推动项目的成功。

在架构重构之前,系统核心业务分散在各个服务中,耦合度较高。通过限界划分和领域建模,我们实现了业务的分离。重构后,系统具备了实时查询功能,数据持久化,并对外提供查询服务。在这个过程中,团队遵循分层设计原则,紧密协作,不断积累和共享领域知识,共同推动项目的成功。

五、总结和思考

1. 项目落地效果

1)组织效率

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

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

  • 领域知识是否得到沉淀,是否有人能承担“领域专家”;

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

2)开发效率

  • 模块粒度是否合适、模块间依赖是否健康;
  • 接口数量是否稳定,不膨胀;
  • 因为功能理解不足引起的bug数量是否低;
  • 模块和接口的自测性程度高不高;
  • 代码可读性,人员交接和新人上手是否足够快。

3)巩固效率之本,分担产品之忧

  • 清晰领域,核心子域重点投入;
  • 统一语言,减少产运研测沟通成本,增加2名研发业务专家;
  • 承接产品需求75%,助力0.5PM;
  • 21个应用微服务,通过DDD领域划分后下降到13个,微服务减少33%;
  • 开发工时3pd以下产品响应效率提升52.3%,3pd以上32.5%,QA工时下降62.3%;
  • 架构、聚合分层,功能分类,新人上手快

2. 思维模型改变

技术团队从被动了解业务转变为主动了解业务,解读业务策略变化,为其定义测量,提出数字化方案。产品经理的核心价值是成为技术与业务之间的桥梁,但通过 DDD,技术同学也更加关注业务,实现产研融合。

1)问题域分析领域建模

  • 分治思维
  • 模型思维
  • 抽象思维
  • 结构化思维

2)模型实现

  • 简单思维
  • 契约思维
  • 解耦思维

3. DDD带来的优劣势及建议

1)优势

  • 隐性知识显性化,统一团队语言
  • 围绕业务变化,隔离“变化”
  • 积木式组合业务演进
  • 关注点分离,隔离技术细节
  • 面向测试、运维
  • 业务思维(主动向前看业务,主动提想法,0.5PM)

2)劣势

  • 团队上手有门槛(概念-理解-困惑-深入理解)

3)使用建议

  • 业务场景复杂
  • 业务变化频繁
  • 重点核心业务领域
  • 可部分取用(分层思想、聚合、限界、架构设计、解耦思维等)
  • 团队共识即正确

业务架构是领域,技术架构是容器,脱离灵魂的容器没有技术意义。

Q&A

Q1:DDD重构时,如何协调产品上线需求的矛盾?

A1:首先,我们在进行 DDD 重构时,要依托公司技术中心的战略,公司对此表示鼓励和倡导;其次,重构模式包括修缮者、绞杀者、演进式。面临与产品上线需求的矛盾时,我们可以选择绞杀者,重新构建优化,在原有业务中也不会影响产品新需求的接入。

Q2:选择COLA架构作为DDD重构业务模型的原因是什么?

A2:首先,COLA 是阿里开源的,具有大厂背书,可信度较高;其次,COLA 具备优秀的分层架构和规范,项目 Github 中提供了最佳实践。如果初期不确定如何进行重构,可以直接参考官方 demo,将其映射到自己的业务中,后期再加入自身见解,进行系统优化。

说在最后

DDD架构如何落地,是是非常常见的面试题。

以上的内容,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,并且在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

当然,关于DDD,尼恩即将给大家发布一波视频 《第34章:DDD的顶奢面经》, 帮助大家彻底穿透DDD。

技术自由的实现路径:

实现你的 架构自由:

吃透8图1模板,人人可以做架构

10Wqps评论中台,如何架构?B站是这么做的!!!

阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了

峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?

100亿级订单怎么调度,来一个大厂的极品方案

2个大厂 100亿级 超大流量 红包 架构方案

… 更多架构文章,正在添加中

实现你的 响应式 自由:

响应式圣经:10W字,实现Spring响应式编程自由

这是老版本 《Flux、Mono、Reactor 实战(史上最全)

实现你的 spring cloud 自由:

Spring cloud Alibaba 学习圣经》 PDF

分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)

一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)

实现你的 linux 自由:

Linux命令大全:2W多字,一次实现Linux自由

实现你的 网络 自由:

TCP协议详解 (史上最全)

网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!

实现你的 分布式锁 自由:

Redis分布式锁(图解 - 秒懂 - 史上最全)

Zookeeper 分布式锁 - 图解 - 秒懂

实现你的 王者组件 自由:

队列之王: Disruptor 原理、架构、源码 一文穿透

缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)

缓存之王:Caffeine 的使用(史上最全)

Java Agent 探针、字节码增强 ByteBuddy(史上最全)

实现你的 面试题 自由:

4800页《尼恩Java面试宝典 》 40个专题

免费获取11个技术圣经PDF: