什么是通用语言

通用语言, 最主要的目的就是减少交流中信息丢失, 在实际开发中, 可能关联很多人, 例如有业务层面的业务细节制定者、领域专家、产品经理、项目经理 、架构师、开发经理、测试经理等等, 即使确定了核心域, 但是对于同样的领域知识, 每个人也有自己的理解, 举个例子, 我们通常说的商品和货物,是不是其实就是一个东西 ? 在销售领域叫商品, 但是一旦进入物流领域就叫货物, 所以我们一说商品就知道这是在销售子域, 一旦说货物就知道这是在物流领域, 如果只用物品来进行交流可能就会丢失信息,因为在不同的子域关注的重点是不同的, 为了减少信息丢失, 确保大家交流的便利性, 将能够简单清晰准确描述业务含义和规则的语言就是领域通用语言, 也就是通用语言是团队统一的语言, 只要你在这个领域, 那么在一个系统生命周期内就应该用通用语言进行交流。

可见, 通用语言作用还是很清晰明了的, 解决沟通障碍节省时间成本, 让大家更好进行协作, 通用语言包含术语与应用场景,并且能够反映在代码中, 例如给领域对象命名, 如商品、订单等,对应实体对象; 而动词则表示一个动作或者事件, 例如商品已经下单, 订单已付款, 运输中等等, 对应领域事件或者说命令。

通用语言贯穿 DDD 的整个设计过程。作为项目团队沟通和协商形成的统一语言,基于它,你就能够开发出可读性更好的代码,将业务需求准确转化为代码设计。

  1. 在事件风暴的过程中,领域专家会和设计、开发人员一起建立领域模型,在领域建模的

    过程中会形成通用的业务术语和用户故事。事件风暴也是一个项目团队统一语言的过

    程。
  2. 通过用户故事分析会形成一个个的领域对象,这些领域对象对应领域模型的业务对象,

    每一个业务对象和领域对象都有通用的名词术语,并且一一映射。
  3. 微服务代码模型来源于领域模型,每个代码模型的代码对象跟领域对象一一对应。

设计过程中我们可以用一些表格,来记录事件风暴和微服务设计过程中产生的领域对象及其属性。比如,领域对象在 DDD 分层架构中的位置、属性、依赖关系以及与代码模型对象的映射关系等。下面是一个微服务设计实例的部分数据,表格中的这些名词术语就是项目团队在事件风暴过程中达成一致、可用于团队内部交流的通用语言。在这个表格里面我们可以看到,DDD 分析过程中所有的领域对象以及它们的属性都被记录下来了,除了 DDD 的领域对象,我们还记录了在微服务设计过程中领域对象所对应的代码对象,并将它们一一映射。

DDD 分析和设计过程中的每一个环节都需要保证限界上下文内术语的统一,在代码模型设计的时侯就要建立领域对象和代码对象的一一映射,从而保证业务模型和代码模型的一致,实现业务语言与代码语言的统一。

如果做到了这一点,也就是建立了领域对象和代码对象的映射关系,那就可以指导软件开发人员准确无误地按照设计文档完成微服务开发了。即使是不熟悉代码的业务人员,也可以很快找到代码的位置。

什么是限界上下文

刚刚有聊到通用语言, 而确定通用语言适用范围, 准确来说, 确定领域范围的就是限界上下文边界, 限界上下文边界英文名bounded context, 如果直接翻译成上下文边界就更容易理解, 主要目的是为了避免同样的概念在不同领域产生不同语义或歧义, DDD在战略上提出"限界上下文"这个概念, 用来确定语义所在的领域边界。

我们可以将限界上下文拆解成两个词语:限界和上下文。 限界就是领域的边界, 而上下文就是语义环境, 通过限界上下文让所有交流的人知道我们聊的是在同一个领域边界内的事情, 合起来就是用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。这个边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,什么不应该在模型中实现。

为什么要有限界上下文这个概念

都说中文这门语言非常丰富,在不同的时空和背景下,同样的一句话会有不同的涵义。有一个例子你应该听说过。在一个明媚的早晨,孩子起床问妈妈:“今天应该穿几件衣服呀?”妈妈回答:“能穿多少就穿多少!”

那到底是穿多还是穿少呢?

如果没有具体的语义环境,还真不太好理解。但是,如果你已经知道了这句话的语义环境,比如是寒冬腊月或者是炎炎夏日,那理解这句话的涵义就会很容易了。所以语言离不开它的语义环境。而业务的通用语言就有它的业务边界,我们不大可能用一个简单的术语没有歧义地去描述一个复杂的业务领域。限界上下文就是用来细分领域,从而定义通用语言所在的边界。现在我们用一个保险领域的例子来说明下术语的边界。

保险业务领域有投保单、核保、财务、回访、保全等保险术语,它们分别应用于保险的不同业务流程。

  1. 客户投保时,业务人员记录投保信息,系统对应有投保单实体对象。
  2. 缴费完成后,业务人员将投保单转为保单,系统对应有保单实体对象,保单实体与投保

    单实体关联。
  3. 如客户需要修改保单信息,保单变为批单,有保全系统对应有批单实体对象,批单实体与保单

    实体关联。
  4. 如果客户发生理赔,生成赔案,系统对应有报案实体对象,报案实体对象与保单或者批单实体关联。投保单、保单、批单、赔案等,这些术语虽然都跟保单有关,但不能将保单这个术语作用在保险全业务领域。因为术语有它的边界,超出了边界理解上就会出现问题。
  5. 正如电商领域的商品一样,商品在不同的阶段有不同的术语,在销售阶段是商品,而在运输阶段则变成了货物。同样的一个东西,由于业务领域的不同,赋予了这些术语不同的涵义和职责边界,这个边界就可能会成为未来微服务设计的边界。看到这,我想你应该非常清楚了,领域边界就是通过限界上下文来定义的。

限界上下文在微服务设计中作用以及意义是什么

接下来,我们对这个概念做进一步的延伸。看看限界上下文和微服务具体存在怎样的关系。我想你买过保险吧,或者听过吧。保险承保的流程包含了投保、缴费、出单等几个主要流程。如果出险了还会有报案、查勘、定损、理算等理赔流程。

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

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

每个领域模型都有它对应的限界上下文,团队在限界上下文内用通用语言交流。领域内所有限界上下文的领域模型构成整个领域的领域模型。理论上限界上下文就是微服务的边界。我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。

可以说,限界上下文是微服务设计和拆分的主要依据。在领域模型中,如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。不过,这里还是要提示一下:除了理论,微服务的拆分还是有很多限制因素的,在设计中不宜过度拆分。那这个度怎么把握好呢?有关微服务设计和具体的拆分方法,我会在实战篇中详细讲解。

总结

通用语言确定了项目团队内部交流的统一语言,而这个语言所在的语义环境则是由限界上下文来限定的,以确保语义的唯一性。而领域专家、架构师和开发人员的主要工作就是通过事件风暴来划分限界上下文。限界上下文确定了微服务的设计和拆分方向,是微服务设计和拆分的主要依据。如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。可以说,限界上下文在微服务设计中具有很重要的意义,如果限界上下文的方向偏离,那微服务的设计结果也就可想而知了。因此,我们只有理解了限界上下文的真正涵义以及它在微服务设计中的作用,才能真正发挥 DDD 的价值,这是基础也是前提。

DDD中限界上下文与通用语言的作用的更多相关文章

  1. IDDD 实现领域驱动设计-理解限界上下文

    上一篇:<IDDD 实现领域驱动设计-理解领域和子域> <实现领域驱动设计>前两章内容,基本上读完了,和<领域驱动设计>不同的是,它把很多的概念都放在前面进行讲述了 ...

  2. DDD理论学习系列(3)-- 限界上下文

    1. 引言 限界上下文可以拆分为两个词,限界和上下文. 限界:是指一个界限,具体的某一个范围. 上下文:个人理解就是语境. 比如我们常说的段子: "我想静静." 这个句子一般是想表 ...

  3. 从壹开始微服务 [ DDD ] 之三 ║ 简单说说:领域、子域、限界上下文

    前言 哈喽大家好,DDD领域驱动设计系列又开始了,前天周二的那篇入门文章中,也收到了一定的效果(写小说的除外),同时我也是倍感鸭梨,怎么说呢,DDD领域驱动设计已经有十年历史了,甚至更久,但是包括我在 ...

  4. DDD之5限界上下文-定义领域边界的利器

    上图是一张普通地图,最刺眼的就是边界? 非常好奇地图绘制工程师是如何描绘如此弯曲多变的边界的?强制行政区域还是人群历史原因自然的人以群分? 我们再换个视角,对工程师或者架构师来说,微服务的边界如何划分 ...

  5. 学习 DDD - 通用语言的模式

    大家好,我是霸戈,这周学习了一些关于领域驱动设计的知识 ,对比较深刻的地方做了不少笔记,分享给大家. 在日常需求讨论的时候,经常会碰到一个需求会议开了一个多小时还没有达成共识.作为业务方(领域专家)明 ...

  6. 【DDD】领域驱动设计实践 —— 限界上下文识别

    本文从战略层面街上DDD中关于限界上下文的相关知识,并以ECO系统为例子,介绍如何识别上下文.限界上下文(Bounded Context)定义了每个模型的应用范围,在每个Bounded Context ...

  7. DDD理论学习系列(1)-- 通用语言

    1.引言 在开始之前,我想我们有必要先了解以下DDD的主要参与者.因为毕竟语言是人说的吗,就像我们面向对象编程一样,那通用语言面向的是? DDD的主要参与者:领域专家+开发人员 领域专家:精通业务的任 ...

  8. DDD - 概述 - 聚合 - 限界上下文 (四)

    最重要的一句话 DDD的所有有相关理论中,只有一句是至关重要的,但是也是最容易被忽略和最难做到的,抛弃传统的设计方式(思路)的思想,这句话起了决定性的作用,但是99%的人都忽略了或者在开始无法正视或理 ...

  9. 1 DDD理论学习1 通用语言

    通用语言就是将事情描述清楚的语言 达到DDD的目标代码即设计,设计即代码.通俗的讲,也就是开发人员写的代码领域专家也能看懂. ddd模式跟传统模式的一个区别在于 传统先创建数据库表 再根据表创建类.而 ...

随机推荐

  1. Pytorch系列:(一)常用基础操作

    各种张量初始化 创建特殊类型的tensor a = torch.FloatTensor(2,3) a = torch.DoubleTensor(2,3) ... 设置pytorch中tensor的默认 ...

  2. 计算机网络——RIP协议:距离向量算法

    路由信息协议(RIP)是内部网关协议(IGP)中使用最广泛的一种协议,它是一种分布式.基于距离向量的路由选择协议,其特点是协议简单.它要求路由器周期性地向外发送路由刷新报文.路由刷新报文主要内容是由若 ...

  3. 手把手教你SonarQube入门安装与使用

    简介 Sonar (SonarQube)是一个开源平台,用于管理源代码的质量. Sonar 不只是一个质量数据报告工具,更是代码质量管理平台. 支持Java, C#, C/C++, PL/SQL, C ...

  4. 也谈如何写一个Webserver(-)

    关于如何写一个Webserver,很多大咖都发表过类似的文章.趁着这个五一假期,我也来凑个份子. 我写Webserver的原因,还得从如何将http协议传送的消息解析说起.当时,我只是想了解一下htt ...

  5. hdu3035 最小割转换成最短路

    题意:       给你一个平面图,要求从求出从左上角到右下角的最小割. 思路:       如果大意的可能直接上来一遍最大流,然后就会各种悲剧的MLE,TLE,其实这个题目可以用到有个论文里面的那个 ...

  6. POJ 2976 01分数规划基础题目

    题意:       给你一组"数",一共n个,每个数有两个权值,价钱a[i],代价b[i],让你选择n - k使得 sigma(a[i]) / sigma(b[i]) * 100 ...

  7. Python脚本模拟登陆DVWA

    目录 requests模拟登陆 Selenium自动化测试登陆 环境:python3.7 windows requests模拟登陆 我们登陆DVWA的时候,看似只有一步:访问网站,输入用户名和密码,登 ...

  8. druid-spring-boot-starter的配置

    #数据源基本信息 spring: datasource: druid: username: root password: 123456 url: jdbc:mysql://localhost:3306 ...

  9. Method Overlonding

    The method overloading is using one single method name with different parameters to created differen ...

  10. 【实用小技巧】spring springmvc集成shiro时报 No bean named 'shiroFilter' available

    查了网上的,很多情况,不同的解决办法,总归一点就是配置文件加载的问题. 先看下配置文件中的配置 web.xml中的主要配置(这是修改后不在报错的:仅仅修改了一个位置:[classpath:spring ...