6、限界上下文:定义领域边界的利器

         在DDD限界上下文:定义领域边界的利器领域建模和微服务建设过程中,会有很多项目参与者,包括领域专家、产品经理、项目经理、架构师、开发经理和测试经理等。对于同样的领域知识,不同的参与者可能会有不同的理解。而且有的时候同一个领域内的名词和术语也可能不统一,团队成员交流起来就会出现障碍,严重时甚至会传达出错误的信息。

如果出现这种情况应该怎么办呢?

在DDD中有“通用语言(Ubiquitous Language)”和“限界上下文(Bounded Context)”这两个重要概念。两者相辅相成,通用语言用于定义上下文对象的含义,而限界上下文则用于定义领域边界,以确保每个上下文对象在它特定的边界内具有唯一的含义,在这个边界内,组合这些对象构建领域模型。

这段描述可能有点抽象,接下来我会一一详细讲解。不过,在这之前,我想先请你看一下这几个问题,这也是本章要讲解的核心内容。

DDD为什么要有限界上下文的概念?除了解决交流障碍,还有其他原因吗?限界上下文在微服务拆分和设计时的作用和意义是什么呢?希望你能带着这几个问题一起进入下面的学习。

1、什么是通用语言

为了更好地理解限界上下文,回答上面的问题,我们先从通用语言讲起。

在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确地描述业务含义和规则的语言就是通用语言。也就是说,通用语言是团队的统一语言,不管你在团队中担任什么样的角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。

那么,通用语言的价值也就很明了了,它可以解决交流障碍的问题,避免因为语言不统一而导致的理解偏差和沟通成本的增加。通用语言不仅能够帮助团队成员更好地理解业务需求,还能够确保在领域模型设计和实现过程中,所有成员都能够准确地理解和传达业务逻辑。

2、什么是限界上下文

那刚刚上面提到的限界上下文又是用来做什么的呢?

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

因为“限界”这个词很少见,而在汉语里“限界”一般是指“铁路建筑物及设备不得超过的轮廓尺寸线”,所以很多人初次接触限界上下文时,就有点犯迷糊,理解成本似乎有点高。

我们不妨先来看一下限界上下文的英文原文:“Bounded Context”,翻译成中文,其实可以理解为“限定了边界的上下文环境”。

为了更好地理解限界上下文的含义,我们可以将它拆解为两个词来理解:“限界”和“上下文”。“限界”是指具体的领域边界,而“上下文”则是业务语义所在的上下文环境。通过限定领域的上下文边界,项目团队就可以在这个特定的业务边界内用无歧义的通用语言进行交流了。

综上,限界上下文就是在限定的上下文环境内,用来封装通用语言和领域对象,保证领域内的一些术语、领域对象等有一个确切的含义,没有语义二义性的一个业务边界。相信你在深入研究DDD后,就能更好地理解它的含义和价值了。它定义了领域模型的边界和业务适用范围,使得团队所有成员能够明确地知道,什么内容应该在领域模型中实现,什么不应该在模型中实现。

如果这个边界限定的是业务领域的边界,那你可以理解为业务上下文边界。

定义限界上下文时通常会考虑领域业务职责单一这个因素。在确定了领域的职责边界后,会将所有与实现该领域职能相关的对象都放在同一个限界上下文边界内,而将所有与该领域职能无关的对象都排除在上下文边界之外。限界上下文就是这样一个强制边界,它可以保证领域职责的单一性和领域模型的纯洁性。

举个例子,其实企业在设置组织架构(如部门、处室等)时,就是在定义企业的限界上下文边界。企业设置组织架构时,往往会从企业的职能边界出发,根据这些职能边界来设置部门,划定部门的边界,比如:可以为人力资源管理相关的职能设置人力资源部,为财务核算管理相关的职能设置财务会计部,还有产品线相关的业务部门以及后勤部门等。

部门的职能边界就是企业组织架构的限界上下文边界。在部门内会聚集与部门职能相关的所有角色,他们在部门内各司其职,共同完成部门所承担的职责。这些角色就类似领域模型中的领域对象。

在确定了部门的职责边界后,不同部门之间的职能就不应该出现重叠和混淆,也不应该将与部门职能不相干的角色放在部门内了,因为这样会破坏组织架构的限界上下文边界。有的企业为了缩减部门编制,会将一些彼此不相干的职能放在一个部门,但是这样在对外提供服务时,就很容易让人产生误解或者困惑,甚至闹出笑话,这就不是一个好的企业限界上下文边界了。

3、进一步理解限界上下文

我们可以通过一些例子进一步理解限界上下文这个概念。不要小看它,彻底弄懂它会给你后面实践DDD和微服务设计打下一个坚实的基础。

都说中文这门语言非常丰富,在不同的时空和背景下,同样的一句话会有不同的含义。

有一个例子你应该听说过。在一个明媚的早晨,孩子起床问妈妈:“今天应该穿几件衣服呀?”妈妈回答:“能穿多少就穿多少!”那到底是穿多还是穿少呢?

简短的几句对话,如果没有具体的上下文语义环境,还真不太好理解。但是,如果你已经知道了这句话所在的语义环境,比如是寒冬腊月或者是炎炎夏日,那么理解这句话的含义就会容易得多了。

所以,语言离不开它的语义环境。同样的,DDD的通用语言也离不开它的语义环境,这个语义环境就是它的业务上下文边界。

在中台领域建模的过程中,我们不大可能用一个简单的名词术语没有歧义地描述一个复杂的业务领域,因此我们就用子域或限界上下文来细分领域,通过缩小术语的业务语义范围,从而限定通用语言所在的上下文边界。

现在我们用一个保险领域的例子来讲解通用语言的限界上下文边界。保险业务领域有投保单、保单、批单和赔案等保险术语,它们分别作用于保险的不同业务流程边界内。

客户投保时,业务人员会记录投保信息,在这个领域内会有投保单实体对象。

缴费完成后,业务人员将投保单转为保单,在这个领域内会有保单实体对象,保单实体与投保单会关联。

如果客户需要修改保单信息,保单会变为批单,在这个领域内会有批单实体对象,批单实体会与保单关联。

如果客户发生理赔,生成了赔案,在这个领域内会有报案实体对象,报案实体对象与保单或者批单关联。

投保单、保单和批单等这些保险术语虽然都跟保单有关,但由于它们在不同的业务阶段,表现形式不一样,也被赋予了特殊的业务含义,我们需要针对不同的业务阶段加以区分,避免出现歧义。因此我们不能简单地用“保单”这个术语作用在保险的全业务领域。通用术语有它的作用边界,超出这个边界就容易出现理解上的问题。

如果你对保险领域不大了解也没关系,电商领域肯定再熟悉不过了吧?正如电商领域的商品一样,商品在不同的阶段也有不同的表达形式。商品在销售阶段是商品,这是它的原始含义。在销售阶段结束后,商品就进入了运输阶段,这时商品就变成了货物。可见,同样的一件商品,由于业务领域边界的不同,这些通用语言的术语就有了不同的含义。

界上下文就是用来定义这些通用语言的上下文边界的。这个边界既是业务领域的边界,也是微服务拆分的边界。

看到这,我想你应该非常清楚了,业务领域的边界就是通过限界上下文来定义的。

4 限界上下文和微服务的关系

接下来,我们来对限界上下文概念做进一步的延伸理解,看一看限界上下文和微服务到底存在怎样的关系?

我们以购买车险为例进行说明。车险承保的流程包含投保、缴费、出单等几个主要流程。如果出险了还会有报案、查勘、定损、理算等理赔流程。

保险领域很复杂,在这里我用一个简化的保险模型来说明限界上下文和微服务的关系,如图6-2所示,还会用到我们在5.1节学到的一些基础知识,比如领域和子域。

图6-2 保险模型的限界上下文

首先,领域可以拆分为多个子领域。一个领域相当于一个问题域,领域拆分为子域的过程就是大问题拆分为小问题的过程。在图6-2里,保险领域被拆分为:投保、支付、保单管理和理赔四个基本的子域。

每个子域可以进一步拆分为更小的子域,比如支付子域还可以进一步拆分为收款和付款子子域。拆分到一定程度后,有些子子域的领域边界就可能变成限界上下文边界了。

子域可能会包含多个限界上下文,如理赔子域就包括报案、查勘和定损等多个限界上下文,这里限界上下文与理赔的子子域领域边界正好重合。也有可能子域的边界正好就是限界上下文边界,如投保子域。

每个领域模型都有它对应的限界上下文,团队在限界上下文内用通用语言交流。领域内所有限界上下文的领域模型构成了整个业务领域的领域模型。

限界上下文是微服务拆分过程中可以参考的业务领域边界。不过,这里还是要提示一下,虽然限界上下文理论上可以作为微服务的拆分边界,但实际落地时,微服务的拆分还是需要结合企业的实际情况,考虑其他非业务因素的限制条件。比如,如果不考虑技术异构、团队沟通等其他外部因素,一个领域模型是可以被设计为一个微服务的。

但需要记住一点:“不宜过度拆分微服务”,这样会增加你的集成和运维成本。

那这个度要如何把握呢?有关微服务拆分和设计的原则,我会在第23章详细讲解。

5、限界上下文与子域的关系

学完第5章和本章后,有人可能会对子域与限界上下文的关系有些困惑。子域和限界上下文的映射关系到底是什么样的?一对多?或者多对一?还是一对一?

其实,在DDD中包括问题域和解决方案域两个不同的维度。问题域主要从业务视角来考虑,完成从领域到子域的分解,而解决方案域则主要从技术实现的角度,通过划分限界上下文和采用DDD战术设计来确定领域模型的技术实现边界。

限界上下文本质上就是子域,只不过它会更多地考虑领域对象的语义边界和技术实现细节。限界上下文的划分体现的是一种更为详细的设计过程,这个过程划分了业务的上下文语义边界,完成了领域模型,明确了领域对象以及领域对象之间的依赖关系等。至此,我们依据限界上下文和领域模型就可以完成微服务设计和落地了。

6、本章小结

通用语言是项目团队内部交流的统一语言,而通用语言的语义上下文环境则是由限界上下文来限定的,这个边界可以确保通用语言无二义性。在确定限界上下文边界时,会用到领域专家的经验。

领域专家和项目团队的主要工作,就是在业务领域内采用事件风暴,来划分限界上下文,建立领域模型。将领域模型映射到微服务,就完成了从业务领域到系统域的映射和系统落地。

限界上下文确定了微服务拆分和设计边界,是微服务拆分和设计的主要依据。如果不考虑技术异构、团队沟通等其他外部因素,一个限界上下文理论上就可以拆分为一个微服务。

可以说,限界上下文在微服务设计中具有很重要的意义,如果划分限界上下文的方向出现了偏离,那微服务设计的结果也就可想而知了。我们只有理解了限界上下文的真正含义和它在微服务设计中的作用,才能真正发挥DDD在微服务拆分和设计中的价值,这是基础也是前提。

7、通俗易懂的限界上下文解释
1、什么是限界上下文

限界上下文(Bounded Context)是领域驱动设计(DDD)中的一个核心概念,用来划分和定义不同业务领域的边界。在每个限界上下文内,特定的术语和概念有明确的含义,确保它们在这个边界内是无歧义的。通过限界上下文,团队可以在复杂的系统中明确各个部分的职责和范围,避免混淆和冲突。

2、通俗的解释

假设我们有一个大杂院,院子里住了很多不同的家庭,每个家庭都有自己的生活空间和规则,这些家庭可以看作是不同的上下文。每个家庭内部都有自己的一套说话方式和做事规则(通用语言),这个家庭的界限就是限界上下文。

举个例子:

  • 家庭A:家庭A的成员在家里说“爸爸”,指的是家庭A的父亲。

  • 家庭B:家庭B的成员在家里说“爸爸”,指的是家庭B的父亲。

如果没有家庭这个边界(限界上下文),大家都住在一个大房子里,那么说“爸爸”的时候就会很混乱,因为不知道指的是哪家的父亲。但是有了家庭这个边界之后,家庭A说的“爸爸”只在家庭A的边界内有效,家庭B说的“爸爸”只在家庭B的边界内有效,这样就不会混淆。

3、在软件中的应用

在软件设计中,限界上下文的概念类似于上述家庭的例子。假设我们在开发一个大型的电商系统,这个系统包括用户管理、订单处理、库存管理等多个部分。每个部分都可以看作是一个限界上下文。

  • 用户管理上下文:在这个上下文中,术语“用户”指的是电商平台的注册用户。

  • 订单处理上下文:在这个上下文中,术语“订单”指的是用户在平台上的购买记录。

  • 库存管理上下文:在这个上下文中,术语“库存”指的是平台上商品的存储数量。

每个上下文都有自己的一套规则和数据,彼此独立。当我们在用户管理上下文中谈论“用户”时,不会与订单处理上下文中的“订单”混淆。

4、具体例子

假设我们在开发一个在线图书销售平台,这个平台包括以下几个限界上下文:

  1. 用户上下文:处理用户注册、登录、信息管理等。

  2. 书籍上下文:管理图书的信息,包括书名、作者、价格等。

  3. 订单上下文:处理用户购买书籍的订单,包括订单创建、支付、发货等。

在用户上下文中,“用户”是一个核心概念,指的是注册并登录的平台用户。在书籍上下文中,“书籍”是一个核心概念,指的是平台上出售的图书。在订单上下文中,“订单”是一个核心概念,指的是用户购买行为的记录。

这些上下文之间虽然有联系,但它们的核心概念和术语在各自的边界内是明确且独立的。这样,即使在不同上下文中使用相同的术语,也不会产生混淆。

小结

限界上下文通过明确定义每个业务领域的边界和通用语言,确保了复杂系统中各个部分的职责和术语不会混淆。在每个限界上下文内,团队成员可以无歧义地交流和合作,从而提高系统的可维护性和可扩展性。通过这个通俗的解释,希望你对限界上下文有了更清晰的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值