领域驱动设计系列文章目录
一、领域驱动设计是什么?
领域驱动设计的英文翻译 Domain-Driven Design,也就是我们常说的 DDD,是一种业务驱动技术的思想模式,简单来说就是通过业务模块拆分领域模型来解耦合。早在20年前就有一些顶尖的技术人员提出了领域建模和设计的重要性,但一直也没有引起太多人的关注,直到微服务的兴起才逐渐浮现在大家面前,那么 DDD 到底帮我们解决了哪些问题呢?
首先,软件的核心是什么?无非就是为用户解决领域相关问题的能力!比如说我们所用微信是一个社交软件,他的核心是解决用户社交领域相关问题的能力,但是随着业务的不断拓展,衍生出了支付、生活服务、交通出行等等各方面业务,此时这个软件已经不是单一领域这么简单了。即使是社交领域也包含了聊天、朋友圈、视频号等很多模块,有些领域在膨胀,边界也在模糊,使它变得很复杂。很多因素会导致项目偏离轨道,但真正决定软件复杂性的是设计方法,当复杂性失去控制时,开发人员就无法理解软件,因此就无法轻易和安全的去更改和拓展它。所以,我们需要领域模型做技术设计支撑。
其次,开发人员对他们工作的领域知识不感兴趣。这个问题很普遍,我见过太多的技术人员热衷于框架细节和底层原理,但是对业务知识很排斥,所以他们不愿拓展自己领域建模的技巧,这也导致抽象和设计能力的停滞,从而产生一个更严重的结果:方向偏离,只是单纯的实现需求,没有从更深层次的理解和解决客户领域问题。所以,我们需要技术人员学习和消化领域知识。
再次,死板的预先规划和设计加重了项目的负担。这是一个很深刻的问题,为什么会有这种问题呢?无非就是缺乏领域知识的指引!很多技术人员接到需求,根本不清楚背后的业务原理和要解决的领域问题,单凭直觉来预测业务的发展,考虑了很多业务根本不可能发展的情况,导致软件冗余繁重。所以,需要技术人员持续学习领域知识来丰富设计。
综合上述的问题,我们需要一个业务专家来拆分领域,建立高效的领域模型和讲解领域知识来指引技术人员做详细设计。所以 DDD 的实质就是消化吸收大量的知识,最后产生一个反应深层次领域知识并聚焦于关键概念的模型。
二、如何运用领域模型
前面我们有提到软件的核心是解决领域问题,那么怎么理解领域,又为什么要运用领域模型呢?每个软件都是为了执行用户的某项活动,或是满足用户的某种需求,这些用户应用软件的问题区域就是软件的领域。为了创建真正能为用户活动所用的软件,开发团队必须运用一套与这些活动有关的知识体系。所需知识的广度可能令人望而生畏,庞大而复杂的信息也可能超乎想象。模型正是解决此类信息超载问题的工具,适当的模型可以使人理解信息的意义,并专注于问题。
1、消化领域知识
- 建立有效模型:建立最初模型,即使这个模型是简陋的;建立基于模型的语言,以便统一团队对领域知识的理解。
- 学习和消化领域知识:建模人员是最初的领域知识消化人员,但知识消化并不是一项孤立的活动,他一般是开发人员和领域专家组成的团队共同协作。
- 持续学习来丰富设计:学习是需要持续的,我们前面所说最初的模型是简陋的,所以我们需要持续不断的学习来丰富模型设计。
- 提炼深层模型:有用的模型很少停留在表面,随着对领域和客户需求的理解逐步加深,我们会丢弃一些最初表面上看起来很重要的元素,或者切换角度。这时,一些最初不被发现的巧妙抽象就会浮出水面,而他们恰恰切中问题要害!
2、统一语言
领域模型可以成为软件项目通用语言的核心,但是一些反映领域知识的专业术语需要统一,在人们共同使用的的那部分业务术语中,那些显而易见的名词在编码时通常被用作对象名称。统一的语言需要大家理解一致,是为了更好的无差别的沟通。我之前做过一个 “非签” 系统(非现场签约),比较直白的意思就是不用到现场,在线上就能签约,但是在创建代码库的时候出现了一个有意思的事情,后端同学命名为 “online-sign”,前端同学却命名 “no-sign”,显然有人对软件要解决的领域问题的理解出现了偏差。良好的代码具有很强的表达能力,你的项目名包名,甚至类名方法名字段名,都应该很清晰的反映出你要解决的领域问题,所以领域模型需要统一语言来规范。
3、绑定模型和实现
MODEL-DRIVEN DESIGN(模型驱动设计):DDD 要求模型不仅能够指导早期的分析工作,更应该作为设计的基础。很多时候我们早期确实建立了不错的模型,但是随着项目的发展,这些模型与项目渐行渐远,甚至还会起误导作用。当程序设计没有绑定模型,仅仅是把功能堆积在一起,最终程序就充斥了大量的功能,难于理解也难于维护。尽管这些功能的实现是比较直观,但是仅通过阅读代码根本无法深入理解该系统的核心目的所在。所以,我们的模型应该是和软件的整个生命周期紧密相关的:软件各个部分的设计应该忠诚的反映领域模型,以便体现二者之间的明确对应关系。我们应该反复检查和修改模型,以便软件可以更加自然的实现模型,即使想让模型反映出更深层次的领域概念时也是如此。
HANDS-ON MODELER(亲身实践的建模者):开发团队中每个成员都有自己的职责,但是将分析、建模、设计和编程工作过度分离会对 MODEL-DRIVEN DESIGN 产生不良影响。很多项目开始的时候,领域专家和各团队的开发负责人共同工作,消化领域知识并提炼出了不错的核心模型,但是该模型却没有派上用场,原因有两个:其一,模型的一些意图在传递过程中丢失;其二,模型与程序实现及技术相互影响,而建模人员没有得到反馈。因此,将建模和编程完全分离是行不通的:代码是模型的表达,改变某些代码就意味着改变了相应的模型,所以每一位开发都必须不同程度的参与模型的讨论并与领域专家保持联系。而建模人员,不管在项目中的主要职责是什么,也应该花时间去了解代码,防止开发人员对模型理解的偏离。