聂同学

一个程序员和架构师的实践与思考

DDD的D、D、D

DDD就是领域驱动设计,这里想要分别谈一下DDD里面的三个D。兼谈一点我们实际的开发团队的DDD实践活动,我们的收获和教训。

第一个D,说的是领域。

是识别和定义问题,这个活动交付给下个阶段的交付物是领域模型。我有个比喻说建模就是在知识的液体海洋中析出晶体。在业界的大量讨论中,讲得比较多的是这个晶体是什么样的,而对于如何析出这样的晶体,却较少有讨论。有人讲了敏捷建模1,但那个也是侧重的是活动安排,不是建模本身的方法论。当然业界也有些建模方法的讨论,比如四色建模法、EventStorm建模法,但这些算是一些局部的方法模式,还没有形成成套路的方法论。

实践中,我们较多的采用功能驱动建模,以功能(或者说UseCase/UseStory)作为起始点,围绕功能提及的业务概念,去逐渐析出周边与之关联的概念。

这里似乎有个“悖论”,我们说领域驱动的好处,就是要跳出功能、迭代的小框框,以更大的时间、空间维度去研究整个业务的总体结构。我们用功能去驱动领域建模,似乎是走回到老路去了。

其实不存在这个悖论,我们举个例子,类比画地图,每个地形采集员他能看到的是当前的一个局部,但这些局部通过地图这个模型逐渐积累起来,再借助一些高层面的观察(比如航拍),就逐渐提供了全局的完备的视野。我们用局部功能去驱动领域建模,也是类似的原理。

第二个D,说的是驱动。

我们之前讨论了什么是驱动,什么样的东西适于驱动2。在DDD的体系中,驱动讲的是MDD,即模型驱动,说的是有一套机械可重复的方法,将领域模型中体现的各个结构,映射为可以解决的问题,也就是可以去开发实现的结构。

实践过程中我们发现。开发团队对第二个D非常敏感,有些同学认为DDD的意义其实就是战术层的一些设计模式,比如工厂、聚合、实体等,认为DDD的存在就是为了“克服贫血的DTO”,使用“充血的实体”。这当然是对DDD的严重误解,完全没有认识到DDD的价值。

就第二个D来说,DDD的好处,要点在“机械、可重复”的映射,这保证了分析与设计的稳定衔接。至于结构性的设计模式,比如聚合、实体这些,只是一个副产物。如果我们能够为这种映射,找到另外一套设计模式,只要能做到“机械、可重复”那也是完全没有问题的。

另外要提醒大家注意的是,这种映射不仅仅是在战术层面,在战略层面同样存在,而且在我们看来具有更为重大的意义。比如子域映射为上下文,上下文之间的关系映射为一些集成模式等等。

第三个D,说的是设计。

紧跟着第二个D,领域模型映射出来的就是设计模型。设计模型作为开发实现的依据。

在实际开发过程中,真正做到依据设计模型进行开发实现,并不是一件理所当然的简单事。因为设计模型不是实现模型,这里是需要一个转换的。

为了解决各种问题,陆陆续续会得到各种设计模型。由于这些解决都需要落实到同一个系统中,它们需要在实现时进行综合。这就是解空间上构建实现模型需要做的事情。从DDD来的设计模型,需要跟应对其他问题来的设计模型进行综合,共同导出实现模型。比如在DDD的同时,我们可能还需要应对分布式带来的容错熔断问题,这就要求我们要作的“防腐层”,兼具在演进时和运行时的隔离功能。

在实际开发过程中容易犯的错,一是没有意识到设计模型与实现模型的区别;二是不能做到正确的综合,容易造成实现模型扭曲了设计模型。

另外

一个图,一个比喻。

方法论, 架构, 过程, 领域, 领域驱动

分享 -