什么是ddd领域驱动设计「DDD架构」
今天给大家普及一下什么是ddd领域驱动设计「DDD架构」相关知识,最近很多在问什么是ddd领域驱动设计「DDD架构」,希望能帮助到您。
前言DDD当然不是什么新概念,该思想源于2003年 Eric Evans编写的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法。从Wiki来看,
领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。
领域模型是对业务模型的抽象,DDD是把业务模型翻译成系统架构设计的一种方式,它倡导:
把项目的主要重点放在核心领域(core domain)和域逻辑把复杂的设计放在有界域(bounded context)的模型上发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题一、领域既然DDD的含义是“领域驱动设计”,那么, 什么是领域(Domain)?
从广义上讲,领域就是一个组织所做的事情以及其中所包含的一切。换句话说,就是一个公司或组织,它所涉及的 业务范围 以及 在其中所进行的活动 。
上面的定义可能较为生涩,那么我们以非常火爆的《斗罗大陆》为例:唐三获得了 杀神领域 和 蓝银领域 。那么,当施展出领域力量之后,在领域内的自己实力大增,而对手的实力却被大幅度削弱。
那么公司也是一样的,我们拿李宁和阿里为例,在运动服饰这个领域中,李宁就远远强于阿里;但是在电商互联网领域中,阿里就强于李宁。所以,用大白话来说解释领域这个词的概念,就是—— 你所经营的、活动的、擅长的那个圈子 。
“领域”这个词的含义是多样化的,它既可以表示 整个业务系统 ,也可以表示其中的某个“ 核心域 ”或者“ 支撑子域 ”。
由于“领域模型”包含了“领域”这个词,我们可能会认为应该为整个业务系统创建一个 单一的、完整的、内聚的、全功能式 的模型,就像《圣斗士星矢》里面的圣衣一样,那么的完整、内聚、功能繁多且强大。
然后,其实正好相反,在DDD中, 一个领域被分为若干个子域,领域模型在限界上下文中完成开发 。事实上,在开发一个领域模型时,我们通常关注的只是这个业务系统的 某个方面 ——某个子域。而无论软件系统本身的复杂度是大还是小,几乎所有软件的领域都包含多个子领域。
二、子域子域根据类型的不同,可分为: 核心域 、 支撑子域 和 通用思域 。以一个音乐网站或者app为例(排除掉版权问题,假设所有数字音乐在各大音乐网站都可以平等播放),它一般包含很多的功能,我们暂且只关注 音乐品味推荐、会员与权限、促销活动 这3部分功能,那么如下就是针对这3部分子域类型的划分:
【解释】
那么如果想要我们的音乐网站或者app脱颖而出受到大众的喜爱,音乐品味推荐会是核心能力,我听了几首歌,后续不知道要听什么歌曲了,而网站给我推荐的歌曲都特别符合我对音乐的品味,那用户自然就更喜欢来这里听歌,那么**“音乐品味推荐”就是核心域**;而网站的各个功能其实都会或多或少的使用会有与权限有关的能力,所以**“会员与权限”就是通用子域**;而“促销活动”这部分也属于业务能力的一部分,但是并没有核心领域那么重要, “促销活动”便是支撑子域 。2.1> 核心域它是整个业务领域的一部分,也是 业务成功的主要促成因素 。从战略层面上讲,企业应该在核心领域上胜人一筹。我们应该给予核心域最高的优先级、最资深的领域专家和最优秀的开发团队。在实施DDD的过程中,你将主要关注于核心域。
2.2> 支撑子域如果某个限界上下文 对应着业务的某些重要方面,但却不是核心 ,那么它便是一个支撑子域。创建支撑子域的原因在于它们专注于业务的某个方面。
2.3> 通用子域如果一个子域 被用于整个业务系统 ,那么这个子域便是通用子域。
三、限界上下文运用限界上下文(BoundedContext)的战略设计模式来 分离领域模型 。一个领域被分为若干个子域,领域模型在 上下文中完成开发 。
在实施DDD的时候,我们要 保证每一个术语应该仅表示一种领域概念 ,即:将用到的每一个术语进行限界划分。这种 基于语言层面 上的上下文边界划分,也是实现DDD的关键。如下所示,同样的“售卖”一词在不同的上下文中含义都是不一样的:
限界上下文是一个 显式的边界 ,领域模型便存在于这个边界之内。领域模型把通用语言表达成软件模型。创建边界的原因在于,每个模型概念,包括它的属性和操作,在边界内都具有特殊的含义。
上面我们介绍限界上下文的时候, 一直再提边界的问题,边界真的这么重要?没有边界,不是一样不影响我们项目的开发迭代吗? 其实不然,在我们试图创建一个“大而全”的软件模型的时候,要使所有人都对某个概念的定义达成一致几乎不可能。因此, 最好的方法是去正视这种不同,然后使用限界上下文对领域模型进行分离 。可以举个例子,在广场上有一群人要商量去哪里,大家各抒己见,无法达成一致。
那怎么办呢?大家谁都不让步。分析原因,广场上的这群人,彼此之间又都是陌生的,那么陌生人也不会轻易地迁就对方,那么我们以家庭进行分组(建立边界),由一家人(即:在同一限界上下文中)内部去商量要去哪里,确定一致性建议。
1
由上面的例子我们可以看到,将不同的家庭分开来,由于一家人是有血缘关系的,所以更容易达成一致。而在DDD中的这种“一家人”,就属于限界上下文,它把一个领域(类比:广场)划分为多个限界上下文,在限界上下文中进行领域建模,同时,这样更容易对某个概念的定义达成一致,建立专属这个限界上下文的领域语言。
四、战略设计的重要性DDD是分为两大部分内容的: 宏观上的——战略设计 和 微观上的——战术设计 。而在上面我们介绍的“领域”、“子域”和“限界上下文”其实都属于战略设计。那么在实施DDD的过程中,我们也需要遵守先执行战略设计,再执行战术设计的方式。那么,战略设计为什么这么重要呢?
其实一提到战略和战术,大部分同学的第一反应应该是在战场上高频出现的词汇,那么我们就 以战场来做解释 。下面是辽沈战役攻打锦州的作战部署图:
从上面的图中我们可以看到,分为了“2C”、“7D”、“8D”、“8C”等作战部队,并且针对每个部队都标注着要攻打的位置和路线。在这张图里,并没有标注用什么枪、用什么炮、用什么手榴弹、多少医护人员……也就是说,不包含打仗的具体细节(战术模式),只在宏观上(战略模式)划分的队伍和攻打方向。如果没有这个宏观的作战图,那么部队将会一盘散沙,各自为战,没有任何配合可言了。这个跟我们DDD中的战略模式是类似的。如下是对应关系:
领域——>攻打锦城子域——>部队核心域——>主力部队,比如:8D支撑域——>其他非主力部队通用域——>通信部队,医疗部队,炊事班限界上下文——>某部队负责攻打的区域通过上面针对战争的例子来看,战略的重要性远不亚于战术,就像人们常常说的那句话—— “方向不对,努力白废!” ,而战略设计就是DDD中的方向。
五、问题空间&解决方案空间领域中还同时存在 问题空间 和 解决方案空间 。它们的含义如下所示:
软件开发过程,本质上可以看作是问题空间到解决方案空间的一个映射转化。
5.1> 问题空间在实际项目中,我们可以针对如下问题, 对问题空间进行评估 :
这个核心域的名字是什么?目标是什么?包含哪些概念?支撑子域和通用子域是什么?如何安排项目人员?能否组件一只合适的团队?5.2> 解决方案空间解决方案空间在很大程度上受到现有系统和技术的影响。在实际项目中,我们可以针对如下问题, 对解决方案空间进行评估 :
有哪些软件资产是存在的?是否可以重用?是否需要创建?是否可以从别的地方获得到?这些资产是如何集成起来的?需要如何集成?假设资产都已经ok了,我们还需要做什么?核心域和支撑项目的成功概率是多少?会不会由于其中一个的失败而导致全盘皆输? 在哪些地方我们使用了完全不同的术语?限界上下文之间在哪些地方存在概念上的重叠?这些重叠的概念在不同的限界上下文之间是如何映射和翻译的?哪些限界上下文包含了核心域中的概念,其中使用了哪些[Evans]中的战术模式?