什么是领域驱动设计?
《领域驱动设计 软件核心复杂性应对之道》这本书是由 Eric Evans “领域驱动设计之父”,世界杰出软件建模专家所写。市面上绝大多数方法论资料的源头都是出自作者。建议大家买来纸质书或电子书看看。
正如这本书的副标题所说,领域驱动设计就是为了解决软件的核心复杂性的。
回首过去
在我以前的软件开发经验中,很多软件都是基于分层思想+贫血模式设计的(如下图)。我从入行就开始学习在MVC模式下进行编码开发。各种框架如strtus、mybatis、hibernate springMVC的应用也都基于此模式来进行。
在多年的开发过程中,经历过
- 用mybatis替换hibernate
- 用springMVC替换struts
- 业务逻辑重重的写在service层,因为太重又进行了多次重构
再回顾下我们的研发流程:一般是从需求开始,产品同学将需求分析完和开发同学进行需求评审,评审完毕后开发同学开始基于需求进行设计,一般会落到数据库设计,将库表设计完毕后,再向上进行分层开发。如果是前后端分离的项目,会在前期约定接口,进行基于契约的并行开发。所以,我们称这种方式为数据驱动开发,或基于数据模型的开发。
聊聊现在
时代在发展,当年一个单体应用就是一个项目和软件,现在一个个的单体都被消灭了,大家也都转向了分布式和微服务。各种拆分、解耦,微服务大行其道,让计算机软件能够承载更多的需求,解决更大的问题。然而有利也有弊,比如:就算单体应用再大,对于一个新人而言,一个业务逻辑debug一趟也基本了解了。而在微服务架构下,一个服务的调用链可能连开发者自己都不一定能梳理清楚(一般要借助工具)。想把所有的逻辑完整的弄清楚是件很困难的事,系统越大越复杂越困难。即便在服务边界内由于代码并没有很清晰的业务概念和描述,也很难快速理解业务逻辑。你可能说这是新人,等新人成长了就好了。(呵呵,新人的体验差真的不解决一下吗?)老人就没有问题吗?当业务逻辑越来越复杂,代码越来越腐败,文档没人维护,留给你的也基本算是一滩沼泽了。我有过这种经历,那种想重新写个新服务的想法特别强烈。
总结来说,我们在新时代拥抱了微服务和分布式解决了很多扩展性上的问题,然后并没有解决软件复杂性的问题,具体来说有:
- 代码没体现业务,光看代码不能支撑你理解业务
- 业务知识没有沉淀下来,对于业务的理解只能找业务专家和技术老人拼图(产品文档更新不及时,最终还是要看代码)
- 软件工程师沦为CURD工程师 (何时能走上业务专家的路?)
- 系统逐渐走向复杂和庞大,对系统的修改由于太过复杂和不甚了解而变得战战兢兢。
- 代码腐败,扩展性差、迭代困难(从立项到重写)
展望未来
幸运的是,我们并不是第一个遇到这种问题的人,在经历了大量类似场景后,前人们归纳总结了解决问题的办法,更幸运的是它与我们流行的微服务、分布式理论又是那么的契合。这就是领域驱动设计。
观察上图,战略和战术设计是站在DDD的角度进行划分。战略设计侧重于高层次、宏观上去划分和集成限界上下文,而战术设计则关注更具体使用建模工具来细化上下文。
DDD战略设计产生的领域模型可以作为微服务设计的输入。此时,DDD的战术设计又恰好可以与微服务的设计完美无缝结合。
(上面这两段话懂的就懂了,不懂的,我们在后文还会再继续阐述,结合前面的知识你一定能明白。)
统一的语言
这是领域驱动设计的第一步,也是非常重要的一步,好的开始是成功的一半。
开发团队与领域专家针对具体问题域与业务期望进行沟通,那么沟通要有统一的语言,不然产品有产品的术语,技术有技术的术语,业务还有业务的术语,大家鸡同鸭讲如何能把事儿说清楚?当然主要还是要依赖于业务,将业务术语和逻辑搞明白了,大家有统一而清晰的认识。(刚开始可能不明白,需要多与业务沟通,了解清楚,从源头就搞错了就尴尬了)。
这是一个将业务领域知识转化的过程,这里最熟悉业务的当然是领域专业或者业务专家,然而我们不是完全把他们所说的原封不动地copy下来,我们是要基于这些业务,用我们的技术知识、产品知识做出可用的软件来,最终它是个软件,我们把这些知识结合在一起,产出一个既满足业务逻辑又是合理的模型抽象。所有甚至有时候技术人员要让领域专家理解技术的解决方法。这样进行反复的沟通才能最终生出好的领域模型。这是建模的过程。
有了统一的认识如何落地?具体来说就是我们要落到纸面上,以便所有相关人员的理解,后面的开发、沟通都要基于这个。一般我们会用画图的方式,当然也可以结合一些文档说明。这就是统一的语言,将模型用统一的语言(图、文档)描述出来。所有人对业务的理解都是一致统一的。
模型,这种知识形式对知识进行了选择性的简化和有意的结构化。适当的模型可以使人理解信息的意义,并专注于问题。
那有没有可用的工具和方法?还真有。(domain story telling )
方法:domain story telling
网站:https://domainstorytelling.org/
建模工具:https://github.com/WPS/domain-story-modeler
最终画出的图类似这样:
domain story telling 只有四类元素来表达领域模型
- actor’s 演员,可以是人、团体或软件系统
- work objects 操作的对象,比如文档、消息等
- activities 动作
- annotations 注释
利用统一的语言最终产出的就是最初的领域概念模型(后面实践篇,我们会看些具体例子)
接下来我们会对这个模型进行领域分析和考虑划分领域,找到领域边界。
未完待续......