领域驱动设计(DDD)这个概念也是最近比较火的,我第一次接触到这个概念,是阿里云的架构师来我们公司交流的时候,当时留意了一下,后面在自己团队工作遇到痛点时才真正开始学习。
为什么选择DDD?
- 重构越来越频繁。每次重构都需要重新梳理业务、重新梳理数据结构,之前的代码也要一行一行的整理和对应,耗费的人力实在太大,甚至超过了重构能带来的好处。
- 代码越来越混乱。慢慢地,已经没法说清楚一个类是什么含义、一个方法是什么含义,大量的业务代码像过程一样揉杂在一起,即使写了注释,也难以理解。
- 团队协作变得困难。慢慢地,某一个开发写的代码,变得只有他自己能维护,其他人看不懂,没法参与进去。
- 缺少必要的数据。想要分析某些旧功能的数据时,发现当初设计这个功能的人只存了该功能所需要的最基本的数据,没有流水记录、也没有留出扩展的空间,甚至某些必要的状态数据也由于产品不关注而没有去记录。
DDD对我们,与其说是一个战术,更多的是一个战略和方法论。
我的第一个DDD系统
第一次尝试,没敢修改已经成熟的系统,做了一个当时比较需要的中间件:实时计算平台。
这一系统主要为了解决的问题是,每次有新的实时计算需求都需要单独去开发一套代码、写一个新的TOPO。考虑用一套可配置化的平台,来解决所有的简单实时计算需求。
按照DDD的思想,我设计这一系统时,划分了两个限界上下文:计算上下文和存储上下文。
计算上下文
计算上下文主要负责微批量实时计算。上游对接某一种消息队列,订阅消息,根据配置在内存中做计算,积攒几秒中之后,将计算结果丢给存储上下文。
存储上下文
存储上下文负责更新数据库。当前主要使用的是关系型数据库PolarDb和NOSQL数据库TableStore。将内存中的计算结果更新到数据库中,若数据库中已有该行数据,则根据计算方法选择求和或是求最大值等等。
初次尝试的感想
整套平台的代码,包括最开始的2、3次功能迭代,都是我自己一个人开发的。当时由于自己的熟悉程度比较高,觉得效果还不错。
后边把项目交给组员去维护时,得到了一些来自组员的反馈。其中最主要的一点就是:大家觉得我是为了做DDD而做DDD。
因为这一系统本身的代码量就不大,拆分成两个上下文之后,上下文之间交互的防腐层就写了大量的代码。而且为了在数据层也解耦,导致数据库设计时多分了几张表,表之间的关联关系比较难理解。
后续
公司正处于微服务转型阶段,解决复杂问题的三种能力:分治、抽象、知识,这几个关键词一直存在于我的脑海中。再加上初次尝试DDD感觉还不错,后边再设计任何系统的时候我都要使用DDD去做。
接下来碰到了一个问题,证明我在实时计算平台的设计思路是正确的。
实时计算平台最早接入的是mysql的binlog日志,后边根据业务需要,还要接入其他团队的业务数据、前端埋点日志、运维监控日志等等。为了避免每次接入新的数据源需要修改代码、重启服务,需要将“数据接入”和“计算/存储”隔离开,这样一来,当初解耦设计的优势就体现出来了。后面考虑了一套系统的方案,把包括实时计算平台、数据同步平台在内的多个中间件整合成了一套完整的数据处理平台。
暂时还没有在核心的、业务复杂的项目中尝试DDD,待我尝试了之后,再来进一步谈谈感想。