全文3073字,预计阅读时间8分钟。<本篇首发于非写不可> DDD系列文章第1篇:初识DDD

导读:本号计划通过一个DDD系列文章全面介绍DDD,包括初识DDD、DDD的知识体系、实施方法和路径、如何领域建模、DDD的分层架构、领域事件架构落地、DDD和BFF、DDD和API First、案例剖析等方面的细节。本篇作为第一篇先尝试回答DDD是什么?能解决什么问题?为什么现在这么火?如何学习DDD?

01

DDD是什么?

DDD的全称是Domain Driven Design,即领域驱动设计。这里的『设计』指软件设计,这里的『领域』跟我们平常说文学领域、工业领域的意思差不多,是指某个或粗或细分的行业。DDD强调软件设计时要体现出领域里大家都熟知的概念,如果是崭新领域也应该尽量提炼出共识性的概念。比如设计电商系统,商品的SKU、SPU概念已经是这个领域的共识了。反过来说如果你的设计里没有这些领域概念,大概率你的设计质量也不会高。因此DDD提倡软件设计要聚焦到所属的业务领域,表达出领域共性知识。

怎么才能理解一个领域,提炼出领域的知识呢?隔行如隔山,只有先充分了解某个领域的细枝末节,在这基础上加以提炼。而提炼就是归类抽象,也就是DDD里的领域建模的意思。因此确切地说是领域模型驱动设计。从业务需求中建模出领域模型,建模的过程就是设计。再把领域模型体现到技术实现中去,通过领域模型来连接业务和代码,保证业务架构和技术架构不脱节,达到理解度高、演变性强的设计质量。

你可能会说,采用传统的软件设计流程不照样开发嘛。的确,如果团队很小,业务很简单,大概什么方法都行。就好比很小的团队里不见得有管理学的发挥空间。DDD的优势在业务领域复杂、涉及到团队协作多的情形。当然现实中只要是商业软件大多都需要多团队协作,业务也需要逐步迭代演进,从这个角度上讲了解一点DDD只有好处。

02

DDD为什么有用?

软件设计和架构的主要目标是治理复杂度,DDD也是为了达到这个目的。DDD是如何理解复杂度呢?先来看一下《领域驱动设计》作者Eric Evans的描述:

领域驱动设计是一种处理高度复杂领域的设计思想,试图通过分离技术实现的复杂性, 围绕业务概念构建领域模型来控制业务的复杂性,以解决软件难以理解,难以演化等问题。

如上述所说复杂度来自两方面,相应地也应从这两方面进行治理:

一是不够模型化结构化,不利于人理解。领域模型就是对业务建模的结果,建模是提取共性,抽象的过程,可以达到降低理解心智,形成共识的目的。具体如何建模在后续系列文章再议。

二是参杂了业务和技术两方面的复杂。这一点很好理解,分而治之是软件设计里最朴实的原则了。比如微服务思想里把一个大系统拆成多个小系统,各自架构和演变,从而把复杂性化整为零。

03

DDD的前世今生,为什么现在这么火?

ddd概念图(DDD系列文章第1篇初识DDD)(1)

从Eric Evans在2003年提出DDD以来至今快20个年头了,在国内的情况总结起来就是前15年不温不火,近3年炙手可热。究其原因可以从需求和供给两方面看。一个新的软件设计方法或技术会流行起来总归要能带来效益,要么能提高开发效率,要么能提高开发质量,或者能提高整个团队的『生产力』比如顺畅的沟通协作。

DDD的需求侧

很长一段时间里行业对DDD的需求都不大。当初Evans提出DDD的年代,大部分开发团队采用的软件开发流程还比较『官僚』,流程细碎,每个工种只关心上游输入方。比如产品经理只和上游业务分析师沟通,设计师从产品经理那得到输入,架构师和设计师沟通,开发人员和架构师沟通等等。总之从需求到最终开发上线需要经历很多流程,每个工种得到的信息都是单向传递的。DDD提倡整个团队一起参与设计,让设计结果贯穿整个流程。但是这要改变很多内部团队的工作方式,而且开发效率不算是一个痛点,大家都没有变革的诉求。

然而近几年企业在市场上面临的竞争压力越来越大,作为成本中心的产研团队需要时时刻刻想到人效,管理层也一直会向产研团队要『效率』。同时大部分企业面临在存量遗留系统上运维和演进,如何快速的理解原有系统是个难题。另一方面微服务和中台的兴起,让业务边界和模块边界的划分变成了一道必修题,这也是需求侧的一个变化。加上数字化时代的加速到来,改造原有系统,连接外部系统这个需求只会更强烈。还有一个我认为需要提一下的隐藏需求就是业务开发人员这个群体需要一个技术体系来成长。而DDD体系聚焦业务,联系业务架构和技术架构,跟业务开发人员的技能十分契合。

DDD的供给侧

一个理论要落地需要有足够的配套设施,否则供给侧就没法满足需求侧。我认为配套设施至少包括理论书籍、技术框架、实践案例分享。DDD给人的感觉都是理论太抽象,没法落地。的确关于DDD的书籍都是偏方法论和设计理念,尽管有战略设计和战术设计的步骤,但毕竟属于设计范畴,很多地方仁者见仁智者见智。但好在目前真正关注和开始实践DDD的人越来越多了,分层架构在多种编程语言下也有了具体的落地形式,各种技术大会上也渐渐开始分享交流DDD了,涉及不同行业的实践案例更多了。等到实践过的人变多了,落地门槛也就降低了。

总结一下就是供给侧还是弱于需求侧。很多公司的软件团队管理层逐渐认识到DDD的优势,对开发效率和质量的追求也引发了需求,但落地门槛还是不低,任重而道远。

04

目前业界落地情况咋样?

从上节的发展历程介绍中也能看到国内一些技术大会比如DDD中国峰会,QCon、ArchSummit等近几年开始有DDD相关话题分享,各大厂都有一些DDD实施经历。从分享的内容上看案例多集中在业务逻辑密集或者数据密集的产品上。比如电商系统的核心模块,金融保险系统,CRM等企业服务软件。

等别人实践了再跟进是比较稳妥的办法,但有时候需要从自身团队和业务情况出发。也许可以在技术重构的时候加入一点业务建模的元素,或者在需求评审环节营造整个团队就核心业务逻辑深入讨论的氛围,再或者对组织架构做一点调整,让业务边界更清晰,资源投入更合理。这些能从业务视角考虑问题的尝试我认为都属于DDD实践。

05

如何学习DDD?

有人说DDD是升级版的面向对象编程思维,某种程度上讲这是对的,具备对现实业务的抽象能力是基本前提。书籍方面建议先读一下非常薄的《领域驱动设计精粹》,了解大致的知识体系。其他几本书都是大部头,可以在实践时遇到问题再按需阅读。框架方面不管是最开始提出的分层架构,还是后来的六边形架构、洋葱架构、整洁架构其实都是类似的,落地时先做到核心一点即可,即让最里层的领域层不依赖其他层。学习DDD更多的还是要在日常需求分析、设计、开发中去体会各种坏味道,其实治理这些坏味道的方法最终都会殊途同归。

学习和实践DDD需要经历一个过程,借用参禅的三重境界,以此提醒大家多学多用多悟。

  • 参禅之初:看山是山,看水是水。初步接触DDD后,开发每行代码都会纠结于DDD的某个原则细节问题,往往忘了DDD的初衷。
  • 禅有悟时:看山不是山,看水不是水。有些DDD实战经验后,往往会怀疑按照DDD设计的东西到底有没有用,特别是当业务还不是很复杂时,受到别人传统方法挑战时。
  • 禅有彻悟:看山仍是山,看水仍是水。比较熟练地掌握了DDD后,才能从容应对各种业务需求开发,对边界和原则拿捏得当。DDD是一种方法论,督促和指导业务开发整个过程要理清业务的本质需求。如果本身的业务需求已经足够简单清晰,是不是DDD已不重要。

06

结语

本篇通过DDD的一些外围知识让你初步了解DDD,要想进一步掌握DDD还需要深入学习DDD的知识体系,比如限界上下文是什么?如何划分?聚合如何设计等等,未完待续!

,