领域驱动建模与框架一直都是大型项目在构建时所讨论的问题,其中引入了很多新颖的概念和理论,但是其相关书籍却晦涩难懂,再加上实际落地的场景很少,且平时项目时间紧缺,并没有那么多时间去设计与思考,导致学习的同学缺乏理论基础和实践经验,很容易让人半途而废。
由于接触到的项目都是领域模型构建,我也进行了相关理论的学习,在这里总结一下自己的学习成果,同时也欢迎大家找我讨论。

在谈论领域概念之前,首先抛出几个问题:

  • 什么是领域驱动设计?
  • 领域驱动相较于传统MVC模型框架有哪些区别?
  • 什么时候适合引入领域驱动设计,它带来了哪些好处?

首先讨论第一个问题,什么是领域驱动设计( 英语:Domain-driven design,缩写 DDD )?

谷歌搜索对它的解释是:
领域驱动设计是帮助开发人员打造优雅的对象系统的原则和模式的集合。 正确应用它可以产生称为领域模型的软件抽象。 这些模型封装了复杂的业务逻辑,缩小了业务现实和代码之间的差距。
wiki的解释是:
领域驱动设计,是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。领域驱动设计的前提是:
把项目的主要重点放在核心领域(core domain)和域逻辑
把复杂的设计放在限界上下文(bounded context)的模型上
发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题
领域驱动设计是一种由域模型来驱动着系统设计的思想,不是通过存储数据词典(DB表字段、ES Mapper字段等等)来驱动系统设计。领域模型是对业务模型的抽象,DDD是把业务模型翻译成系统架构设计的一种方式

我们来解释一下释义中的名词,以帮助大家理解
对象系统:面向对象系统设计,是指以人类的对象思维来抽象现实世界,并以此表达信息世界中事物的思想,举个🌰 :一只小狸猫可以是一个对象,那么它的毛发颜色、瞳孔颜色、体重、年龄等等这些都是它的属性,一直小柴犬也是如此,它们二者之间同时也存在一些相同的属性,例如都是哺乳动物,那么它们就可以抽象一层哺乳动物层,按照这个思路,我们还可以继续往上提炼,这就体现了面向对象的思想:类和对象都体现了抽象的思想,抽出对象(们)共同的/本质的特征。

软件抽象:顾名思义,其实就是软件设计的一种原则,称之为抽象原则,抽象的例子在上面已经讲过,那我们可以结合其一起来看看SOLID原则。

  • 单一指责原则:一个模块只做一件事,抽象的核心体现。
  • 开放封闭原则:开放封闭原则是指对扩展开放,对修改封闭。当需求改变时,我们可以扩展模块以满足新的需求,但扩展时,不应该需要修改原模块的实现。但在这里面向对象可能也会破坏这个原则,所以这是相对的,如何去进行抽象,取决于我们对未来可能的扩展的预判。
  • 依赖倒置原则:依赖倒置原则是指高层模块不应该依赖于低层模块的实现,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖与抽象。
  • 里氏替换原则:里氏替换原则是指子类必须能够替换成它们的基类,如果一个抽象不能符合里氏替换原则,那我们就需要考虑下这个抽象是不是合适了。
  • 接口隔离原则:接口隔离原则是指客户端不应该被迫依赖它们不使用的方法。如果一个抽象不符合接口隔离原则,那可能就不是一个合适的抽象。

核心领域:领域表示的是一种特定的范围或区域,专门活动或事业的范围、部类或部门。领域用来确定范围和边界,将业务上的问题限定归属在特定的边界内,领域就是这个边界内要解决的业务问题域。比如,一个保险公司的领域中包含了保险、理赔等概念。在DDD中,我们对系统的划分是基于领域的,也是基于业务的。其中为了降低业务理解和系统实现的复杂度,可以将领域进一步划分成更小范围的问题,称为子域,如果需要可以对子域进一步划分形成子子域。有一个文章的例子挺好的,比如研究的对象是桃树,那么果实、根、茎叶是领域,但是如果在果实领域进一步研究,还需要研究组织甚至细胞,那么组织就是果实的子域、细胞是组织的子域,为了区分不用子域的功能属性与重要性,给予不同的关注度,各个子域又分为核心域、通用域、支撑域。

限界上下文:领域边界上下文,主要是对域进行划分,为什么要有限界上下文这个概念?日常人与人之间的沟通交流,单单从别人口中的一个单词一句话很难理解到表达者的真实意图,尤其中华文化博大精深,比如说到“小米”,如果没有上下文,你很难知道表达的是粮食小米,还是小米名牌小米手机等。因此,为了避免同样的词语产生歧义,一定要结合到语言上下文中去理解其真正的语义。限界上下文就是用来细分领域,从而定义通用语言所在的边界。限界上下文包含两部分:限界(Bounded)和上下文(Context)。限界就是领域的边界,而上下文就是语义环境。限界上下文用来封装通用语言和领域对象,提供上下文环境,任何领域对象都只表示特定于该边界内部的确切含义,保证在领域之内的一些术语、业务相关对象等概念有一个确切的含义,从而让所有交流的人讨论的范围在同一个领域边界内。

存储数据词典(DB表字段、ES Mapper字段等等)来驱动系统设计:传统的MVC项目是从需求业务中拆解不同的实体,通过ER模型建立不同实体的属性以及其两两之间的关系,从何确定数据库设计以及业务实现

DDD是把业务模型翻译成系统架构设计的一种方式:这是领域驱动与传统MVC对于项目架构上的不同点,DDD中项目架构更偏向于业务驱动,而MVC只是将软件分为三个基本部分:模型,视图和控制器,这个我们在第二个问题再做详细讨论。