引言 | 本文作者从微信团队维护的带货类项目所遇卡点出发,尝试用领域驱动设计方法(简称DDD),保障在快节奏、多人协作的项目迭代中,维持系统的可维护性、可拓展性、高内聚低耦合和稳定性。作者首先剖解相关概念原理,之后代入亲身参与的微信团队实际项目、围绕DDD方法进行优化实操。

**DDD 全称 Domain-Driven Design,中文叫领域驱动设计,是一套应对复杂软件系统分析和设计的面向对象建模方法论。**它由Eric Evans于2003年提出,但一开始不愠不火。直到MartinFowler于2014年发表论文《Microservices》,引起大家对微服务的关注,至此DDD重新慢慢的回到了大众的视野中。

DDD这几年升温的同时,也受到了很多行业人员对DDD的负面意见。主要原因大概有“晦涩难懂过于抽象”、“很难找到实际的案例参考”、“不知道怎么落地”等。

在学习DDD的过程中,我们也遇到上述卡点。但经过几个月持续学习和实践DDD,我们对其思想、价值、应用方法有更深入了解。这里尝试用白话去总结我们DDD从入门到实践的全过程,尽量每一个概念都用我们的具体实现做出例子,希望能对想一起学习DDD的开发者们有所帮助。

一个维护中的业务系统引出的思考

我所在微信团队由后台和前端工程师一起维护某带货类的项目,这个项目我们用了最传统的三层模型来搭建,大概是如下的模型:

当这个项目维护几年之后,逐渐出些了一些有意思的情况,我挑选一些主要环节发现的代表性问题介绍下:

情况1(代码层面):少部分代码可读性在长期不同人员的修改下变得越来越差。如某个带货的核心rpc逻辑没有任何嵌套平铺在一个函数,单函数代码行数达到几百行,可读性和维护性极差,成功化身为“技术护城河”。

情况2(微服务层面): 某些微服务初始职能划分较为简单,导致少量模块在后续高频迭代中快速膨胀。如其中的mp模块,原本职能是用来承接B端门户的功能;当我们决定拆分这个庞大的模块时,这个模块已经承载了204个rpc。过多的能力承担让它编译变慢、变成链路单点、改动较多、一旦出现问题影响较大。

情况3(业务团队层面):带货项目会使用一些其他业务系统的接口和数据结构。当这些业务系统想要修改这些接口和数据结构的时候 ,一方面可能未察觉这里的依赖将导致线上问题, 另一方面可能在业务间沟通后发现耦合处比较多,不容易改动。

维护这个项目的过程中,我们进行了一些思考:在一个复杂业务系统中,代码结构要如何设计、微服务的横/纵向职能要如何划分、业务团队之间如何交互,才能保障在快节奏、多人协作的项目迭代中,维持系统的可维护性、可拓展性、高内聚低耦合和稳定性。

而传统的开发模式不管是面向过程(POP)还是面向对象(OOP)的思维,都没办法从微服务层面指导我们找到这些问题的答案。但我们发现,有两种方法解决这个问题:

1.寻找一个总是有时间、总能做出正确决策的中心节点同事,介入每一处全局/细节的设计并统一做出决策。

2.寻找一个新的规则/规范来做指导,让每一位开发工作者都能有做出正确决策的依据。

在Tencent的氛围和环境中,第二个方法无疑是更合理的,所以我们想到了领域驱动设计(DDD)。

DDD的分层架构

DDD最有标志性的一点,就是将传统软件设计三层模型转化为了四层模型,这个转化如下图所示: