DDD中限界上下文与通用语言的作用
什么是通用语言
通用语言, 最主要的目的就是减少交流中信息丢失, 在实际开发中, 可能关联很多人, 例如有业务层面的业务细节制定者、领域专家、产品经理、项目经理 、架构师、开发经理、测试经理等等, 即使确定了核心域, 但是对于同样的领域知识, 每个人也有自己的理解, 举个例子, 我们通常说的商品和货物,是不是其实就是一个东西 ? 在销售领域叫商品, 但是一旦进入物流领域就叫货物, 所以我们一说商品就知道这是在销售子域, 一旦说货物就知道这是在物流领域, 如果只用物品来进行交流可能就会丢失信息,因为在不同的子域关注的重点是不同的, 为了减少信息丢失, 确保大家交流的便利性, 将能够简单清晰准确描述业务含义和规则的语言就是领域通用语言, 也就是通用语言是团队统一的语言, 只要你在这个领域, 那么在一个系统生命周期内就应该用通用语言进行交流。
可见, 通用语言作用还是很清晰明了的, 解决沟通障碍节省时间成本, 让大家更好进行协作, 通用语言包含术语与应用场景,并且能够反映在代码中, 例如给领域对象命名, 如商品、订单等,对应实体对象; 而动词则表示一个动作或者事件, 例如商品已经下单, 订单已付款, 运输中等等, 对应领域事件或者说命令。
通用语言贯穿 DDD 的整个设计过程。作为项目团队沟通和协商形成的统一语言,基于它,你就能够开发出可读性更好的代码,将业务需求准确转化为代码设计。
- 在事件风暴的过程中,领域专家会和设计、开发人员一起建立领域模型,在领域建模的
过程中会形成通用的业务术语和用户故事。事件风暴也是一个项目团队统一语言的过
程。 - 通过用户故事分析会形成一个个的领域对象,这些领域对象对应领域模型的业务对象,
每一个业务对象和领域对象都有通用的名词术语,并且一一映射。 - 微服务代码模型来源于领域模型,每个代码模型的代码对象跟领域对象一一对应。
设计过程中我们可以用一些表格,来记录事件风暴和微服务设计过程中产生的领域对象及其属性。比如,领域对象在 DDD 分层架构中的位置、属性、依赖关系以及与代码模型对象的映射关系等。下面是一个微服务设计实例的部分数据,表格中的这些名词术语就是项目团队在事件风暴过程中达成一致、可用于团队内部交流的通用语言。在这个表格里面我们可以看到,DDD 分析过程中所有的领域对象以及它们的属性都被记录下来了,除了 DDD 的领域对象,我们还记录了在微服务设计过程中领域对象所对应的代码对象,并将它们一一映射。
DDD 分析和设计过程中的每一个环节都需要保证限界上下文内术语的统一,在代码模型设计的时侯就要建立领域对象和代码对象的一一映射,从而保证业务模型和代码模型的一致,实现业务语言与代码语言的统一。
如果做到了这一点,也就是建立了领域对象和代码对象的映射关系,那就可以指导软件开发人员准确无误地按照设计文档完成微服务开发了。即使是不熟悉代码的业务人员,也可以很快找到代码的位置。
什么是限界上下文
刚刚有聊到通用语言, 而确定通用语言适用范围, 准确来说, 确定领域范围的就是限界上下文边界, 限界上下文边界英文名bounded context, 如果直接翻译成上下文边界就更容易理解, 主要目的是为了避免同样的概念在不同领域产生不同语义或歧义, DDD在战略上提出"限界上下文"这个概念, 用来确定语义所在的领域边界。
我们可以将限界上下文拆解成两个词语:限界和上下文。 限界就是领域的边界, 而上下文就是语义环境, 通过限界上下文让所有交流的人知道我们聊的是在同一个领域边界内的事情, 合起来就是用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。这个边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,什么不应该在模型中实现。
为什么要有限界上下文这个概念
都说中文这门语言非常丰富,在不同的时空和背景下,同样的一句话会有不同的涵义。有一个例子你应该听说过。在一个明媚的早晨,孩子起床问妈妈:“今天应该穿几件衣服呀?”妈妈回答:“能穿多少就穿多少!”
那到底是穿多还是穿少呢?
如果没有具体的语义环境,还真不太好理解。但是,如果你已经知道了这句话的语义环境,比如是寒冬腊月或者是炎炎夏日,那理解这句话的涵义就会很容易了。所以语言离不开它的语义环境。而业务的通用语言就有它的业务边界,我们不大可能用一个简单的术语没有歧义地去描述一个复杂的业务领域。限界上下文就是用来细分领域,从而定义通用语言所在的边界。现在我们用一个保险领域的例子来说明下术语的边界。
保险业务领域有投保单、核保、财务、回访、保全等保险术语,它们分别应用于保险的不同业务流程。
- 客户投保时,业务人员记录投保信息,系统对应有投保单实体对象。
- 缴费完成后,业务人员将投保单转为保单,系统对应有保单实体对象,保单实体与投保
单实体关联。 - 如客户需要修改保单信息,保单变为批单,有保全系统对应有批单实体对象,批单实体与保单
实体关联。 - 如果客户发生理赔,生成赔案,系统对应有报案实体对象,报案实体对象与保单或者批单实体关联。投保单、保单、批单、赔案等,这些术语虽然都跟保单有关,但不能将保单这个术语作用在保险全业务领域。因为术语有它的边界,超出了边界理解上就会出现问题。
- 正如电商领域的商品一样,商品在不同的阶段有不同的术语,在销售阶段是商品,而在运输阶段则变成了货物。同样的一个东西,由于业务领域的不同,赋予了这些术语不同的涵义和职责边界,这个边界就可能会成为未来微服务设计的边界。看到这,我想你应该非常清楚了,领域边界就是通过限界上下文来定义的。
限界上下文在微服务设计中作用以及意义是什么
接下来,我们对这个概念做进一步的延伸。看看限界上下文和微服务具体存在怎样的关系。我想你买过保险吧,或者听过吧。保险承保的流程包含了投保、缴费、出单等几个主要流程。如果出险了还会有报案、查勘、定损、理算等理赔流程。
首先,领域可以拆分为多个子领域。一个领域相当于一个问题域,领域拆分为子域的过程就是大问题拆分为小问题的过程。在这个图里面保险领域被拆分为:投保、支付、保单管理和理赔四个子域。
子域还可根据需要进一步拆分为子子域,比如,支付子域可继续拆分为收款和付款子子域。拆到一定程度后,有些子子域的领域边界就可能变成限界上下文的边界了。子域可能会包含多个限界上下文,如理赔子域就包括报案、查勘和定损等多个限界上下文(限界上下文与理赔的子子域领域边界重合)。也有可能子域本身的边界就是限界上下文边界,如投保子域。
每个领域模型都有它对应的限界上下文,团队在限界上下文内用通用语言交流。领域内所有限界上下文的领域模型构成整个领域的领域模型。理论上限界上下文就是微服务的边界。我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。
可以说,限界上下文是微服务设计和拆分的主要依据。在领域模型中,如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。不过,这里还是要提示一下:除了理论,微服务的拆分还是有很多限制因素的,在设计中不宜过度拆分。那这个度怎么把握好呢?有关微服务设计和具体的拆分方法,我会在实战篇中详细讲解。
总结
通用语言确定了项目团队内部交流的统一语言,而这个语言所在的语义环境则是由限界上下文来限定的,以确保语义的唯一性。而领域专家、架构师和开发人员的主要工作就是通过事件风暴来划分限界上下文。限界上下文确定了微服务的设计和拆分方向,是微服务设计和拆分的主要依据。如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。可以说,限界上下文在微服务设计中具有很重要的意义,如果限界上下文的方向偏离,那微服务的设计结果也就可想而知了。因此,我们只有理解了限界上下文的真正涵义以及它在微服务设计中的作用,才能真正发挥 DDD 的价值,这是基础也是前提。
DDD中限界上下文与通用语言的作用的更多相关文章
- IDDD 实现领域驱动设计-理解限界上下文
上一篇:<IDDD 实现领域驱动设计-理解领域和子域> <实现领域驱动设计>前两章内容,基本上读完了,和<领域驱动设计>不同的是,它把很多的概念都放在前面进行讲述了 ...
- DDD理论学习系列(3)-- 限界上下文
1. 引言 限界上下文可以拆分为两个词,限界和上下文. 限界:是指一个界限,具体的某一个范围. 上下文:个人理解就是语境. 比如我们常说的段子: "我想静静." 这个句子一般是想表 ...
- 从壹开始微服务 [ DDD ] 之三 ║ 简单说说:领域、子域、限界上下文
前言 哈喽大家好,DDD领域驱动设计系列又开始了,前天周二的那篇入门文章中,也收到了一定的效果(写小说的除外),同时我也是倍感鸭梨,怎么说呢,DDD领域驱动设计已经有十年历史了,甚至更久,但是包括我在 ...
- DDD之5限界上下文-定义领域边界的利器
上图是一张普通地图,最刺眼的就是边界? 非常好奇地图绘制工程师是如何描绘如此弯曲多变的边界的?强制行政区域还是人群历史原因自然的人以群分? 我们再换个视角,对工程师或者架构师来说,微服务的边界如何划分 ...
- 学习 DDD - 通用语言的模式
大家好,我是霸戈,这周学习了一些关于领域驱动设计的知识 ,对比较深刻的地方做了不少笔记,分享给大家. 在日常需求讨论的时候,经常会碰到一个需求会议开了一个多小时还没有达成共识.作为业务方(领域专家)明 ...
- 【DDD】领域驱动设计实践 —— 限界上下文识别
本文从战略层面街上DDD中关于限界上下文的相关知识,并以ECO系统为例子,介绍如何识别上下文.限界上下文(Bounded Context)定义了每个模型的应用范围,在每个Bounded Context ...
- DDD理论学习系列(1)-- 通用语言
1.引言 在开始之前,我想我们有必要先了解以下DDD的主要参与者.因为毕竟语言是人说的吗,就像我们面向对象编程一样,那通用语言面向的是? DDD的主要参与者:领域专家+开发人员 领域专家:精通业务的任 ...
- DDD - 概述 - 聚合 - 限界上下文 (四)
最重要的一句话 DDD的所有有相关理论中,只有一句是至关重要的,但是也是最容易被忽略和最难做到的,抛弃传统的设计方式(思路)的思想,这句话起了决定性的作用,但是99%的人都忽略了或者在开始无法正视或理 ...
- 1 DDD理论学习1 通用语言
通用语言就是将事情描述清楚的语言 达到DDD的目标代码即设计,设计即代码.通俗的讲,也就是开发人员写的代码领域专家也能看懂. ddd模式跟传统模式的一个区别在于 传统先创建数据库表 再根据表创建类.而 ...
随机推荐
- mybatis的本质和原理
背景 项目需要,我们需要自己做一套mybatis,或者使用大部分mybatis的原始内容.对其改造,以适应需要.这就要求我再次学习一下mybatis,对它有更深入的了解. 是什么 MyBatis ...
- Redis持久化——AOF日志
最新:Redis内存--内存消耗(内存都去哪了?) 最新:Redis持久化--如何选择合适的持久化方式 最新:Redis持久化--AOF日志 更多文章... 上一篇文章Redis持久化--内存快照(R ...
- 老学长的TODOLIST
初期: 一.基本算法: (1)枚举(poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法 (4)递推 (5)构造法(poj3295)(这种 ...
- hdu3338 最大流
题意: 给你一个N*M的网格,上面有的有一些数字,要求填充数字,满足的规则是这样: 答案不唯一,只要满足和的关系就可以,还有就是只能用1--9之间的数字填充,而且每一行或一列可 ...
- C++处理char*,char[],string三种类型间的转换
前言 在C和C++中,有一个相当重要的部分,就是字符串的编程描述.在学C的时候,很多人习惯了char[],char*表示法,直到遇见了C++后,出现了第三者:string.这时候,很多初学者就会在这三 ...
- 开启Android应用调试选项的工具XDebug的介绍
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/81187769 最近这段时间比较郁闷,就不分享和学习比较复杂的Android逆向技 ...
- 【apache】使用HttpClient,进行简单网页抓取
1 package com.lw.httpclient.test; 2 import org.apache.http.client.methods.CloseableHttpResponse; 3 i ...
- JAVA连接、操作数据库的DBHelper
工厂模式的DBHelper 1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.Prepa ...
- 【odoo】[经验分享]数据迁移注意事项
[odoo14]经典好书学习没有烂尾,主体已完成,可移步了解.https://www.cnblogs.com/xushuotec/p/14428210.html 背景 近期,有朋友打算上odoo系统. ...
- JavaScript中DOM与BOM的区别
1.BOM BOM全称为Brower Object Model,中文翻译为浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象.描述了与浏览器进行交互的方法和接口.通过BOM可以用来获取或设置 ...