领域驱动设计 —— 名词解释

DDD实战课 - 02

DD 的知识体系提出了很多的名词:领域、子域、核心域、通用域、支撑域、限界上下文、聚合、聚合根、实体、值对象等等。

领域

简言之,DDD 的领域就是这个边界内要解决的业务问题域。

领域就是用来确定范围的,范围即边界。在研究和解决业务问题时,DDD 会按照一定的规则将业务领域进行细分,当领域细分到一定的程度后,DDD 会将问题范围限定在特定的边界内,在这个边界内建立领域模型,进而用代码实现该领域模型,解决相应的业务问题。领域的核心思想就是将问题域逐级细分,来降低业务理解和系统实现的复杂度。通过领域细分,逐步缩小微服务需要解决的问题域,构建合适的领域模型,而领域模型映射成系统就是微服务了。


子域

领域是用来限定业务边界和范围的,那么就会有大小之分,领域越大,业务范围就越大,反之则相反。

领域可以进一步划分为子领域。我们把划分出来的多个子领域称为子域,每个子域对应一个更小的问题域或更小的业务范围。


举例_领域和子域:

比如保险是个比较大的领域,很早以前的保险核心系统把所有的功能都放在一个系统里来实现,这个系统就是我们常说的单体系统。

后来单体系统开始无法适应保险业务的发展,因此保险公司开始了中台转型,引入分布式微服务架构来替换原来的单体系统。而分布式微服务架构就需要划分业务领域边界,建立领域模型,并实现微服务落地了。为实现保险领域建模和微服务建设,我们可以根据业务关联度以及流程边界将保险领域细分为:承保、收付、再保以及理赔等子域,而承保子域还可以继续细分为投保、保全(寿险)、批改(财险)等子子域。在投保这个限界上下文内可以建立投保的领域模型,投保的领域模型最后映射到系统就是投保微服务。这就是一个保险领域的细分和微服务的建设过程。


核心域、通用域、支撑域

在领域不断划分的过程中,领域会细分为不同的子域,子域可以根据自身重要性和功能属性划分为三类子域,它们分别是:核心域、通用域和支撑域。

  • 核心域 : 决定产品和公司核心竞争力的子域是核心域,它是业务成功的主要因素和公司的核心竞争力。
  • 通用域 :没有太多个性化的诉求,同时被多个子域使用的通用功能子域是通用域。企业应用中的通用系统,比如认证、权限等等,这类应用很容易买到,没有企业特点限制,不需要做太多的定制化。
  • 支撑域 : 还有一种功能子域是必需的,但既不包含决定产品和公司核心竞争力的功能,也不包含通用功能的子域,它就是支撑域。而支撑域则具有企业特性,但不具有通用性,例如 数据代码类的数据字典(元数据)等系统。

划分目的

核心域、支撑域和通用域的主要目标是:通过领域划分,区分不同子域在公司内的不同功能属性和重要性,从而公司可对不同子域采取不同的资源投入和建设策略,其关注度也会不一样。很多公司的业务,表面看上去相似,但商业模式和战略方向是存在很大差异的,因此公司的关注点会不一样,在划分核心域、通用域和支撑域时,其结果也会出现非常大的差异。

对于研究桃树来讲:桃树就是领域,我们将桃树细分为了根、茎、叶、花、果实和种子等六个子域。

那桃树是否有核心域?有的话,到底哪个是核心域呢?核心域的确定需要根据桃树所处的场景,不同的人对桃树的理解是不同的。

  • 如果这棵桃树生长在公园里,在园丁的眼里,他喜欢的是“人面桃花相映红”的阳春三月,这时花就是桃树的核心域。
  • 但如果这棵桃树生长在果园里,对果农来说,他则是希望在丰收的季节收获硕果累累的桃子,这时果实就是桃树的核心域。

在不同的场景下,不同的人对桃树核心域的理解是不同的,因此对桃树的处理方式也会不一样。园丁更关注桃树花期的营养,而果农则更关注桃树落果期的营养,有时为了保证果实的营养供给,还会裁剪掉疯长的茎和叶(通用域或支撑域)。


限界上下文

DDD实战课 - 03

在 DDD 领域建模和系统建设过程中,有很多的参与者,包括领域专家、产品经理、项目经理、架构师、开发经理和测试经理等。对同样的领域知识,不同的参与角色可能会有不同的理解,那大家交流起来就会有障碍,怎么办呢?因此,在 DDD 中就出现了“通用语言”和“限界上下文”这两个重要的概念。

问题:

  1. 为什么要提出限界上下文的概念(也就是说除了解决交流障碍这个广义的原因,还有更具体的吗)?
  2. 限界上下文在微服务设计中的作用和意义是什么?

通用语言:

在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言就是通用语言。也就是说,通用语言是团队统一的语言,不管你在团队中承担什么角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。那么,通用语言的价值也就很明了了,它可以解决交流障碍这个问题,使领域专家和开发人员能够协同合作,从而确保业务需求的正确表达。

通用语言包含术语和用例场景,并且能够直接反映在代码中。通用语言中的名词可以给领域对象命名,如商品、订单等,对应实体对象;而动词则表示一个动作或事件,如商品已下单、订单已付款等,对应领域事件或者命令。

 

限界上下文:

语言都有它的语义环境,同样,通用语言也有它的上下文环境。为了避免同样的概念或语义在不同的上下文环境中产生歧义,DDD 在战略设计上提出了“限界上下文”这个概念,用来确定语义所在的领域边界。

限界上下文拆解为两个词:限界和上下文。限界就是领域的边界,而上下文则是语义环境。通过领域的限界上下文,我们就可以在统一的领域边界内用统一的语言进行交流。

综合一下,我认为限界上下文的定义就是:用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。这个边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,什么不应该在模型中实现。

 

举例_限界上下文和通用语言:

用一个保险领域的例子来说明下术语的边界。保险业务领域有投保单、保单、批单、赔案等保险术语,它们分别应用于保险的不同业务流程。

  • 客户投保时,业务人员记录投保信息,系统对应有投保单实体对象。
  • 缴费完成后,业务人员将投保单转为保单,系统对应有保单实体对象,保单实体与投保单实体关联。
  • 如客户需要修改保单信息,保单变为批单,系统对应有批单实体对象,批单实体与保单实体关联。
  • 如果客户发生理赔,生成赔案,系统对应有报案实体对象,报案实体对象与保单或者批单实体关联。

投保单、保单、批单、赔案等,这些术语虽然都跟保单有关,但不能将保单这个术语作用在保险全业务领域。同一张保单在不同的阶段有不同的术语。因为术语有它的边界,超出了边界理解上就会出现问题。


举例_领域和子域和限界上下文

领域:保险领域

子域:领域可以拆分为多个子领域。一个领域相当于一个问题域,领域拆分为子域的过程就是大问题拆分为小问题的过程。

在这个图里面保险领域被拆分为:投保、支付、保单管理和理赔四个子域。子域还可根据需要进一步拆分为子子域,比如,支付子域可继续拆分为收款和付款子子域。拆到一定程度后,有些子子域的领域边界就可能变成限界上下文的边界了。
子域可能会包含多个限界上下文,如理赔子域就包括报案、查勘和定损等多个限界上下文(限界上下文与理赔的子子域领域边界重合)。也有可能子域本身的边界就是限界上下文边界,如投保子域。

上限界上下文:理论上限界上下文就是微服务的边界。

我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。可以说,限界上下文是微服务设计和拆分的主要依据。在领域模型中,如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。

 


实体和值对象

DDD实战课 - 04

实体和值对象的关系实体和值对象是微服务底层的最基础的对象,一起实现实体最基本的核心领域逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值