美文网首页领域驱动程序员
DDD——在我梦里,我还能让你把我给欺负了?

DDD——在我梦里,我还能让你把我给欺负了?

作者: 爪哇缪斯 | 来源:发表于2022-07-04 13:35 被阅读0次

    在《夏洛特烦恼》中有这么的一段剧情:夏洛穿越到了他初中的班级里,当他发现自己在梦中的时候,看着一直讽刺挖苦他的老师说了句经典的台词:“在我梦里,我还能让你把我给欺负了?”。他能说出这么“男人”的话,就是因为这是他的梦,是他的“领域”,他是这个梦里面的“王”。

    那么在DDD中也有领域的概念,团队中的同学们也是所负责领域中的“王”。通过领域,我们会引出另外两个概念,即:子域和限界上线文。那么,在今天的文章里,我们就好好的聊一聊他们的故事。

    在我梦里,我还能让你把我给欺负了?

    一、领域

    既然DDD的含义是“领域驱动设计”,那么,什么是领域(Domain)?

    从广义上讲,领域就是一个组织所做的事情以及其中所包含的一切。换句话说,就是一个公司或组织,它所涉及的业务范围以及在其中所进行的活动

    上面的定义可能较为生涩,那么我们以非常火爆的《斗罗大陆》为例:唐三获得了杀神领域蓝银领域。那么,当施展出领域力量之后,在领域内的自己实力大增,而对手的实力却被大幅度削弱。

    唐三获得了杀神领域和蓝银领域

    那么公司也是一样的,我们拿李宁和阿里为例,在运动服饰这个领域中,李宁就远远强于阿里;但是在电商互联网领域中,阿里就强于李宁。所以,用大白话来说解释领域这个词的概念,就是——你所经营的、活动的、擅长的那个圈子

    企业在各自的领域中

    “领域”这个词的含义是多样化的,它既可以表示整个业务系统,也可以表示其中的某个“核心域”或者“支撑子域”。

    由于“领域模型”包含了“领域”这个词,我们可能会认为应该为整个业务系统创建一个单一的、完整的、内聚的、全功能式的模型,就像《圣斗士星矢》里面的圣衣一样,那么的完整、内聚、功能繁多且强大。

    单一的、完整的、内聚的、全功能式的模型

    然后,其实正好相反,在DDD中,一个领域被分为若干个子域,领域模型在限界上下文中完成开发。事实上,在开发一个领域模型时,我们通常关注的只是这个业务系统的某个方面——某个子域。而无论软件系统本身的复杂度是大还是小,几乎所有软件的领域都包含多个子域。

    在DDD中,一个领域被分为若干个子域

    二、子域

    子域根据类型的不同,可分为:核心域支撑子域通用子域。以一个音乐网站或者app为例(排除掉版权问题,假设所有数字音乐各大音乐网站都可以平等播放),它一般包含很多的功能,我们暂且只关注音乐品味推荐、会员与权限、促销活动这3部分功能,那么如下就是针对这3部分子域类型的划分:

    核心域、支撑子域和通用子域

    【解释】

    - 那么如果想要我们的音乐网站或者app脱颖而受收到大众的喜爱,音乐品味推荐会是核心能力,我听了几首歌,后续不知道要听什么歌曲了,而网站给我推荐的歌曲都特别符合我对音乐的品味,那用户自然就更喜欢来这里听歌,那么“音乐品味推荐”就是核心域

    - 而网站的各个功能其实都会或多或少的使用会有与权限的能力,所以“会员与权限”就是通用子域

    - 而“促销活动”这部分也属于业务能力的一部分,但是并没有核心域那么重要,“促销活动”便是支撑子域

    2.1> 核心域

    它是整个业务领域的一部分,也是业务成功的主要促成因素。从战略层面上讲,企业应该在核心域上胜人一筹。我们应该给予核心域最高的优先级、最资深的领域专家和最优秀的开发团队。在实施DDD的过程中,你将主要关注于核心域。

    核心域

    2.2> 支撑子域

    如果某个限界上下文对应着业务的某些重要方面,但却不是核心,那么它便是一个支撑子域。创建支撑子域的原因在于它们专注于业务的某个方面。

    支撑子域

    2.3> 通用子域

    如果一个子域被用于整个业务系统,那么这个子域便是通用子域。

    通用子域

    三、限界上下文

    运用限界上下文(BoundedContext)的战略设计模式来分离领域模型。一个领域被分为若干个子域,领域模型在限界上下文中完成开发

    在实施DDD的时候,我们要保证每一个术语应该仅表示一种领域概念,即:将用到的每一个术语进行限界划分。这种基于语言层面上的上下文边界划分,也是实现DDD的关键。如下所示,同样的“售卖”一词在不同的上下文中含义都是不一样的:

    限界上下文

    限界上下文是一个显式的边界,领域模型便存在于这个边界之内。领域模型把通用语言表达成软件模型。创建边界的原因在于,每个模型概念,包括它的属性和操作,在边界内都具有特殊的含义。

    限界上下文&领域模型

    上面我们介绍限界上下文的时候,一直再提边界的问题,边界真的这么重要?没有边界,不是一样不影响我们项目的开发迭代吗? 其实不然,在我们试图创建一个“大而全”的软件模型的时候,要使所有人都对某个概念的定义达成一致几乎不可能。因此,最好的方法是去正视这种不同,然后使用限界上下文对领域模型进行分离。可以举个例子,在广场上有一群人要商量去哪里,大家各抒己见,无法达成一致。

    在广场上有一群人要商量去哪里

    那怎么办呢?大家谁都不让步。分析原因,广场上的这群人,彼此之间又都是陌生的,那么陌生人也不会轻易的迁就对方,那么我们以家庭进行分组(建立边界),由一家人(即:在同一限界上下文中)内部去商量要去哪里,确定一致性建议。

    根据领域分离,确定一致想法

    由上面的例子我们可以看到,将不同的家庭分界开来,由于一家人是有血缘关系的,所以更容易达成一致。而在DDD中的这种“一家人”,就属于限界上下文,它把一个领域(类比:广场)划分为多个限界上下文,在限界上下文中进行领域建模,同时,这样更容易对某个概念的定义达成一致,建立专属这个限界上下文的领域语言。

    四、战略设计的重要性

    DDD是分为两大部分内容的:宏观上的——战略设计微观上的——战术设计。而在上面我们介绍的“领域”、“子域”和“限界上下文”其实都属于战略设计。那么在实施DDD的过程中,我们也需要遵守先执行战略设计,再执行战术设计的方式。那么,战略设计为什么这么重要呢?

    其实一提到战略和战术,大部分同学的第一反应应该是在战场上高频出现的词汇,那么我们就以战场来做解释。下面是辽沈战役攻打锦州的作战部署图:

    作战部署图

    从上面的图中我们可以看到,分为了“2C”、“7D”、“8D”、“8C”等作战部队,并且针对每个部队都标注着要攻打的位置和路线。在这张图里,并没有标注用什么枪、用什么炮、用什么手榴弹、多少医护人员……也就是说,不包含打仗的具体细节(战术模式),只在宏观上(战略模式)划分的队伍和攻打方向。如果没有这个宏观的作战图,那么部队将会一盘散沙,各自为战,没有任何配合可言了。这个跟我们DDD中的战略模式是类似的。如下是对应关系:

    • 领域——>攻打锦城

    • 子域——>部队

    • 核心域——>主力部队,比如:8D

    • 支撑域——>其他非主力部队

    • 通用域——>通信部队,医疗部队,炊事班

    • 限界上下文——>某部队负责攻打的区域

    通过上面针对战争的例子来看,战略的重要性远不亚于战术,就像人们常常说的那句话——“方向不对,努力白废!”,而战略设计就是DDD中的方向。

    五、问题空间&解决方案空间

    领域中还同时存在问题空间解决方案空间。它们的含义如下所示:

    问题空间和解决方案空间

    软件开发过程,本质上可以看作是问题空间到解决方案空间的一个映射转化。

    5.1> 问题空间

    在实际项目中,我们可以针对如下问题,对问题空间进行评估

    • 这个核心域的名字是什么?目标是什么?包含哪些概念?

    • 支撑子域和通用子域是什么?

    • 如何安排项目人员?能否组件一只合适的团队?

    5.2> 解决方案空间

    解决方案空间在很大程度上受到现有系统和技术的影响。在实际项目中,我们可以针对如下问题,对解决方案空间进行评估

    • 有哪些软件资产是存在的?是否可以重用?是否需要创建?是否可以从别的地方获得到?

    • 这些资产是如何集成起来的?需要如何集成?

    • 假设资产都已经ok了,我们还需要做什么?

    • 核心域和支撑项目的成功概率是多少?会不会由于其中一个的失败而导致全盘皆输?

    • 在哪些地方我们使用了完全不同的术语?

    • 限界上下文之间在哪些地方存在概念上的重叠?这些重叠的概念在不同的限界上下文之间是如何映射和翻译的?

    • 哪些限界上下文包含了核心域中的概念,其中使用了哪些[Evans]中的战术模式?


    相关文章

      网友评论

        本文标题:DDD——在我梦里,我还能让你把我给欺负了?

        本文链接:https://www.haomeiwen.com/subject/xpdsbrtx.html