极客时间已完结课程限时免费阅读

03 | 限界上下文:定义领域边界的利器

03 | 限界上下文:定义领域边界的利器-极客时间

03 | 限界上下文:定义领域边界的利器

讲述:欧创新

时长14:18大小13.06M

你好,我是欧创新。今天我们重点学习“限界上下文”。
在 DDD 领域建模和系统建设过程中,有很多的参与者,包括领域专家、产品经理、项目经理、架构师、开发经理和测试经理等。对同样的领域知识,不同的参与角色可能会有不同的理解,那大家交流起来就会有障碍,怎么办呢?因此,在 DDD 中就出现了“通用语言”和“限界上下文”这两个重要的概念。
这两者相辅相成,通用语言定义上下文含义,限界上下文则定义领域边界,以确保每个上下文含义在它特定的边界内都具有唯一的含义,领域模型则存在于这个边界之内。你是不是感觉这么描述很抽象?没关系,接下来我会给你一一详细讲解。
在这之前,我想请你先看这样两个问题,这也是今天内容的核心。
为什么要提出限界上下文的概念(也就是说除了解决交流障碍这个广义的原因,还有更具体的吗)?
限界上下文在微服务设计中的作用和意义是什么?

什么是通用语言?

为了更好地理解限界上下文,回答这两个问题,我们先从通用语言讲起。
怎么理解通用语言这个概念呢?在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言就是通用语言。也就是说,通用语言是团队统一的语言,不管你在团队中承担什么角色,在同一个领域的软件生命周期里都使用统一的语言进行交流。
那么,通用语言的价值也就很明了了,它可以解决交流障碍这个问题,使领域专家和开发人员能够协同合作,从而确保业务需求的正确表达。
但是,对这个概念的理解,到这里还不够。
通用语言包含术语和用例场景,并且能够直接反映在代码中。通用语言中的名词可以给领域对象命名,如商品、订单等,对应实体对象;而动词则表示一个动作或事件,如商品已下单、订单已付款等,对应领域事件或者命令。
通用语言贯穿 DDD 的整个设计过程。作为项目团队沟通和协商形成的统一语言,基于它,你就能够开发出可读性更好的代码,将业务需求准确转化为代码设计。
下面我带你看一张图,这张图描述了从事件风暴建立通用语言到领域对象设计和代码落地的完整过程。
在事件风暴的过程中,领域专家会和设计、开发人员一起建立领域模型,在领域建模的过程中会形成通用的业务术语和用户故事。事件风暴也是一个项目团队统一语言的过程。
通过用户故事分析会形成一个个的领域对象,这些领域对象对应领域模型的业务对象,每一个业务对象和领域对象都有通用的名词术语,并且一一映射。
微服务代码模型来源于领域模型,每个代码模型的代码对象跟领域对象一一对应。
这里我再给你分享一条经验,我自己经常用,特别有效。设计过程中我们可以用一些表格,来记录事件风暴和微服务设计过程中产生的领域对象及其属性。比如,领域对象在 DDD 分层架构中的位置、属性、依赖关系以及与代码模型对象的映射关系等。
下面是一个微服务设计实例的部分数据,表格中的这些名词术语就是项目团队在事件风暴过程中达成一致、可用于团队内部交流的通用语言。在这个表格里面我们可以看到,DDD 分析过程中所有的领域对象以及它们的属性都被记录下来了,除了 DDD 的领域对象,我们还记录了在微服务设计过程中领域对象所对应的代码对象,并将它们一一映射。
到这里,我要再强调一次。DDD 分析和设计过程中的每一个环节都需要保证限界上下文内术语的统一,在代码模型设计的时侯就要建立领域对象和代码对象的一一映射,从而保证业务模型和代码模型的一致,实现业务语言与代码语言的统一。
如果你做到了这一点,也就是建立了领域对象和代码对象的映射关系,那就可以指导软件开发人员准确无误地按照设计文档完成微服务开发了。即使是不熟悉代码的业务人员,也可以很快找到代码的位置。

什么是限界上下文?

那刚刚提到的限界上下文又是用来做什么的呢?
我们知道语言都有它的语义环境,同样,通用语言也有它的上下文环境。为了避免同样的概念或语义在不同的上下文环境中产生歧义,DDD 在战略设计上提出了“限界上下文”这个概念,用来确定语义所在的领域边界。
我们可以将限界上下文拆解为两个词:限界和上下文。限界就是领域的边界,而上下文则是语义环境。通过领域的限界上下文,我们就可以在统一的领域边界内用统一的语言进行交流。
综合一下,我认为限界上下文的定义就是:用来封装通用语言和领域对象,提供上下文环境,保证在领域之内的一些术语、业务相关对象等(通用语言)有一个确切的含义,没有二义性。这个边界定义了模型的适用范围,使团队所有成员能够明确地知道什么应该在模型中实现,什么不应该在模型中实现。

进一步理解限界上下文

我们可以通过一些例子进一步理解一下这个概念,不要小看它,彻底弄懂会给你后面实践 DDD 打下一个坚实的基础。
都说中文这门语言非常丰富,在不同的时空和背景下,同样的一句话会有不同的涵义。有一个例子你应该听说过。
在一个明媚的早晨,孩子起床问妈妈:“今天应该穿几件衣服呀?”妈妈回答:“能穿多少就穿多少!”
那到底是穿多还是穿少呢?
如果没有具体的语义环境,还真不太好理解。但是,如果你已经知道了这句话的语义环境,比如是寒冬腊月或者是炎炎夏日,那理解这句话的涵义就会很容易了。
所以语言离不开它的语义环境。
而业务的通用语言就有它的业务边界,我们不大可能用一个简单的术语没有歧义地去描述一个复杂的业务领域。限界上下文就是用来细分领域,从而定义通用语言所在的边界。
现在我们用一个保险领域的例子来说明下术语的边界。保险业务领域有投保单、保单、批单、赔案等保险术语,它们分别应用于保险的不同业务流程。
客户投保时,业务人员记录投保信息,系统对应有投保单实体对象。
缴费完成后,业务人员将投保单转为保单,系统对应有保单实体对象,保单实体与投保单实体关联。
如客户需要修改保单信息,保单变为批单,系统对应有批单实体对象,批单实体与保单实体关联。
如果客户发生理赔,生成赔案,系统对应有报案实体对象,报案实体对象与保单或者批单实体关联。
投保单、保单、批单、赔案等,这些术语虽然都跟保单有关,但不能将保单这个术语作用在保险全业务领域。因为术语有它的边界,超出了边界理解上就会出现问题。
如果你对我从事的保险业不大了解也没关系,电商肯定再熟悉不过了吧?
正如电商领域的商品一样,商品在不同的阶段有不同的术语,在销售阶段是商品,而在运输阶段则变成了货物。同样的一个东西,由于业务领域的不同,赋予了这些术语不同的涵义和职责边界,这个边界就可能会成为未来微服务设计的边界。看到这,我想你应该非常清楚了,领域边界就是通过限界上下文来定义的。

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

接下来,我们对这个概念做进一步的延伸。看看限界上下文和微服务具体存在怎样的关系。
我想你买过车险吧,或者听过吧。车险承保的流程包含了投保、缴费、出单等几个主要流程。如果出险了还会有报案、查勘、定损、理算等理赔流程。
保险领域还是很复杂的,在这里我用一个简化的保险模型来说明下限界上下文和微服务的关系。这里还会用到我们在 [第 02 讲] 学到一些基础知识,比如领域和子域。
首先,领域可以拆分为多个子领域。一个领域相当于一个问题域,领域拆分为子域的过程就是大问题拆分为小问题的过程。在这个图里面保险领域被拆分为:投保、支付、保单管理和理赔四个子域。
子域还可根据需要进一步拆分为子子域,比如,支付子域可继续拆分为收款和付款子子域。拆到一定程度后,有些子子域的领域边界就可能变成限界上下文的边界了。
子域可能会包含多个限界上下文,如理赔子域就包括报案、查勘和定损等多个限界上下文(限界上下文与理赔的子子域领域边界重合)。也有可能子域本身的边界就是限界上下文边界,如投保子域。
每个领域模型都有它对应的限界上下文,团队在限界上下文内用通用语言交流。领域内所有限界上下文的领域模型构成整个领域的领域模型。
理论上限界上下文就是微服务的边界。我们将限界上下文内的领域模型映射到微服务,就完成了从问题域到软件的解决方案。
可以说,限界上下文是微服务设计和拆分的主要依据。在领域模型中,如果不考虑技术异构、团队沟通等其它外部因素,一个限界上下文理论上就可以设计为一个微服务。
不过,这里还是要提示一下:除了理论,微服务的拆分还是有很多限制因素的,在设计中不宜过度拆分。那这个度怎么把握好呢?有关微服务设计和具体的拆分方法,我会在实战篇中详细讲解。

总结

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

思考题

现在,不妨回头看看,开头的两个问题你能回答了吗?你可以尝试用自己的话来总结一下。
最后再给你留一个作业,你能找一找自己工作中的通用语言和限界上下文吗?可以把你的答案和感受写下来,分享到留言区,与我一起讨论。也欢迎你把今天的内容分享给同事和朋友,邀请他一起学习。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 57

提建议

上一篇
02 | 领域、子域、核心域、通用域和支撑域:傻傻分不清?
下一篇
04 | 实体和值对象:从领域模型的基础单元看系统设计
 写留言

精选留言(125)

  • 蚂蚁内推+v
    2019-10-20
    限界上下文大概是直译过来的一个晦涩的术语,理解成本较高。 英文是bounded context,应该叫上下文边界更合适。

    作者回复: 是的,赞一个。

    共 7 条评论
    111
  • LY
    2019-10-18
    老师,我有一个问题,对于你们保险行业来说,投保单、保单、批单、赔案,这些领悟概念都是在不同的限界上下文中,那么就是在不同的微服务中,拆分开以后,如果管理后台有一个需求,需要查出一个列表,列表的字段信息需要这些所有不同类型的订单的组合。 1这种查询你们会放在哪个微服务里做呢 2对于组合查询这种情况你们是连表查询,或者是不同服务通过id查询来提供属于它自己的那部分信息的,还是有更好的办法呢。
    展开

    作者回复: 这种跨多个微服务的数据查询。对于准实时的查询,你可以考虑数据中台。在数据中台会归拢所有的微服务的数据,在数据中台提供统一的各个维度数据的集中查询。对于实时性要求高的,你可以考虑一定的数据冗余,上游的业务数据做完后,实时写入到需要联表查询的库中,写入时只写入必要的数据就可以了。

    共 10 条评论
    68
  • Lambor
    2020-07-19
    老师您好,关于领域划分想咨询下。 先说下背景,我的公司是做企业软件实施的,公司有技术中台、大数据中台、业务中台,我所在的技术中台是做通用框架平台的,主要是避免重复造轮子。基于 SpringCloud 开发了很多通用微服务和通用基础组件,比如网关服务、用户权限管理服务、认证服务、平台服务、消息服务、文件服务、支付服务、OCR服务、NLP服务、工作流服务等等。在给客户实施软件时,通过选配需要的服务即可搭建起一个基础平台,然后重点关注客户的核心业务服务开发。 首先关于核心域、通用域、支撑域的问题,像我所在技术中台这个领域内,我觉得所有的服务都属于我们的核心域,公司的战略就是成立技术中台来解决技术统一、通用能力沉淀、复用的问题,各个微服务其实没太多内在关联,都是通用微服务和组件。但要放到客户项目或者业务中台的产品,在他们的领域内,这些服务就变成了通用域或支撑域,而他们则把核心资源放到他们自身的业务上,那才是他们的核心域。这也应了文中说的商业模式的不同会导致核心域划分结果的不同。不知道这样理解有没有问题,主要是对技术中台这个领域的理解。 然后是我负责的用户权限管理服务,我觉得这个服务现在越来越重了,加的功能越来越多,也不太清楚如何划分这个领域,所以想请教下。我们最开始虽然采用了DDD的战术设计,但实际实施出来还是面向过程式的,以数据库驱动的方式来设计的。 主要的功能有:租户管理、用户管理、用户组管理、菜单管理、角色管理、客户端管理(OAuth2的客户端)、权限管理(API) 主要的动作有: 用户分配角色、用户分配工作台卡片 客户端分配角色 角色分配菜单权限、角色分配用户、角色分配客户端、角色分配数据权限、角色分配工作台卡片、角色分配字段权限、角色分配单据权限 角色创建又有复制、继承、直接创建三种创建方式 菜单下有创建目录、菜单、维护API权限等 其中工作台卡片、单据权限、数据权限是在平台服务进行数据维护的,平台服务和用户权限服务共用一个schema。 后面由于业务需求,又增加了安全组管理,相当于权限的集合,安全组分配菜单权限、数据权限、工作台卡片、字段权限、单据权限,然后角色增加了分配安全组的功能。 然后最近还增加了三员管理(保密系统的系统管理员、安全保密员、安全审计员),不过这个是开发的一个服务插件,是可插拔的。 个人感觉整个用户权限服务越来越大、功能交错复杂,但又不好划分,而且由于代码层面各个功能耦合度较高,想拆分也比较难。 但说实在的,我们是做通用框架的,要满足各个项目的功能需求以及方便项目上定制化功能逻辑,个人觉得代码水平还可以,代码质量和扩展性上不是问题。但现在我想通过DDD的方式来试着重构这个服务,而且我们现在有些功能也正面临这拆分重组的问题。 这门课程我已经学完一遍了,如果按我的理解通过DDD的方式来重新拆分领域边界,将设计如下聚合: 租户聚合: 实体:租户 动作:创建租户 事件:租户初始化事件(租户初始化时会初始化其它的一些数据) 权限聚合: 实体:菜单、权限、用户、客户端、角色、租户 值对象:工作台卡片、字段权限、单据权限、数据权限,这些应该是通过远程服务获取的(那应该是DTO?还是建成值对象?) 动作: 菜单实体:菜单创建、目录创建、分配权限 权限实体:查询权限 用户实体:创建用户、修改密码 客户端实体:创建客户端 角色实体:创建角色、继承创建、复制创建 领域服务: 权限分配服务:分配角色菜单权限、分配角色卡片、分配角色字段权限、分配角色数据权限、分配角色单据权限、分配角色用户、分配角色客户端(我不是很确定是应该单独划分领域服务还是放到角色实体里面) 安全组聚合: 实体:安全组 值对象:菜单权限、卡片、字段权限、数据权限、单据权限、角色 领域服务: 安全组分配服务:处理角色和安全组的关系 应用服务: 安全组应用服务:通过服务编排,组合权限聚合中的权限分配领域服务,处理安全组下的菜单权限、卡片、数据权限等于角色的分配关系。 三员聚合: 实体:无 值对象:角色、菜单权限等 领域服务:三员角色领域服务 以上是我的个人理解,还望老师指点。我主要是想了解针对我们这种通用域类型的底层框架服务,好不好用DDD的战略和战术设计,又怎么划分边界,而且一定要满足功能的扩展,逻辑自定义。
    展开

    作者回复: 内容比较多,不知道理解的对不对?不对的地方请指出。 在设计的时候要考虑聚合的职责单一原则。我大概梳理一下,这里面有些功能是基础数据管理和配置,如用户、租户、菜单、角色配置等,有些是多个聚合数据组合后形成的聚合,比如用户权限聚合。 第一、要完成权限管理功能会有用户或者租户。这些数据都是非常基础的实体,完成用户和租户基础数据管理,因此会有用户或租户聚合,聚合根分别是用户和租户。 用户和租户这一块应该在一个限界上下文内。 第二、系统中会有菜单等基础数据配置,因此会有菜单管理相关的聚合,聚合根是菜单。 第三、在进行权限设置时,首先需要定义角色(角色是不是岗位的意思?),角色定义完成后实际上是一种通用静态配置数据吧,角色关联菜单(一对多),字段,数据以及单据等实体,因此会有角色(岗位)聚合。但需要注意:如果不同用户角色的菜单权限一样,但是数据权限或者单据权限不同,这样设计就可能不合适,这时数据权限和单据权限就不能关联到角色了。这里不清楚你说的数据权限和单据权限是否需要单独维护和管理,如果需要独立维护就可以独立为数据和单据权限等的基础数据配置的聚合。 第四、菜单权限、卡片、字段权限、数据权限、单据权限、角色等多个值对象权限组合为一个安全组,形成安全组聚合。 第五、用户(租户)与角色或安全组权限结合一起形成用户(租户)权限,因此会有用户权限聚合,用户权限是聚合根,它会关联安全组或用户、角色、数据等其他聚合的数据,用户、角色、数据以值对象的形式被用户权限聚合根引用。 三员管理我理解也应该是角色相关的管理。 第二到第五的内容应该在一个权限相关的限界上下文内。 第六、考虑到登录,应该还有账户聚合,账户是聚合根,完成密码和登录管理,另外账户会引用用户值对象。这些内容在一个限界上下文内。 完成这些聚合设计后,聚合之间的协调可以通过应用服务来实现。

    共 42 条评论
    66
  • stg609
    2019-10-22
    谢谢老师的文章,很受用。我们公司也在实践DDD, 但是遇到很多问题。其中之一就是不能合理的定义这个BC。能不能具体说下如何去划分这个限界上下文?或者说根据什么去判断边界在哪? 往往对于很熟悉的领域比如您所处于的保险,或者电商,由于很熟悉,所以有些边界是一目了然的,比如销售上下文,库存上下文等。但是假设你处于一个完全陌生的领域,该怎样一步一步识别出这个上下文边界呢?
    展开

    作者回复: 限界上下文划分主要依据是业务的语义边界,比如客户的环境下只说客户相关的事情,权限环境下只定义权限相关的业务逻辑。对于陌生业务环境,经过分析,你基本能够知道有哪些流程和场景,这些流程和场景里应该有对应的语义环境。 而在具体的分析过程中,在确定一个子域,并完成事件风暴后,你可以找出实体和聚合,实体和聚合根他们有业务属性和逻辑。你基本知道这个聚合可以作什么样的业务,如果多个聚合共同完整这类业务,你就可以把多个聚合放在一个限界上下文内,这样一个限界上下文就形成了。

    共 2 条评论
    48
  • 朱振光
    2019-10-22
    从事件风暴到代码落地的5个步骤中,并没有提到子域划分和bounded context的划分,这个两个步骤应该在哪一步进行呢?bounded context划分是直接基于子域里面划分,还是在整个领域内划分,最后再和子域mapping?

    作者回复: 做子域划分的主要目的就是把问题域细分,然后你才能做事件风暴,子域太大你hold不住!这些细分的子域是相对较大的领域,在事件风暴之前先做子域细分。子域细分后,你就可以在子域内用事件风暴建立领域模型,建模过程中会对聚合进行归类,形成限界上下文边界。这个限界上下文,其实你也可以认为是一个子域。

    共 2 条评论
    24
  • 新新
    2020-04-07
    已经是第三遍刷了,第一遍只记住了DDD是微服务拆分的利器,第二遍记住了领域、子域、界限上下文、聚合等这些概念,第三遍有了一些自己的理解,对应领域、子域、界限上下文我是这样理解的: 1、领域对系统的一级划分,如果划分为领域已经可以进行事件风暴,则没有必要再拆分为子域,直接在领域内进行事件风暴。 2、子域是个相对概念,在一个大系统里的子域可能比一个小系统的领域还要大,比如有两个平台,一个平台是京东级的电商平台,一个是小图书馆的管理系统,电商平台的用户子域,比图书管理系统的用户领域要大的多。对小系统而言,可能没有子域的概念,系统划分领域后,直接在领域上进行事件风暴。 3、界限上下文与领域、子域最大的区别是,上下文是在事件风暴后产生的,事件风暴后产生的上下文可能反过来会影响子域的划分。 4、界限上下文一直是理解的难点,一个动作是一个界限上下文?比如用户登录;还是一个名词是一个界限上下文?比如用户。我的理解是一个界限上下文是都可以,界限上下文最大的作用是限定哪些名词和动作是在这个界限内的,比如用户管理可以做为一个界限上下文(子域),用户登录和注册就在这个上下文内,设备的管理就不在这个上下文内,所以就不属于这个上下文(子域),代码实现的时候,设备相关的操作就不应该在用户管理服务里实现。
    展开

    作者回复: 多看几遍理解就是不一样啊。

    共 3 条评论
    23
  • TH
    2019-10-18
    以前基于模块的编程方式,会将不同业务中属于同一个对象的功能都写到这个对象的类中,导致这个类非常庞大,从逻辑上来说也将复杂的业务耦合到了一起。如果使用DDD的方式来设计系统,比如文中所举的保单的例子,应该不同的业务线或者说不同的限界上下文内都应当实现自己的保单对象,对应到微服务就是以限界上下文来划分服务,而不是以对象或功能集来划分服务,因此不存在一个单独的“保单”服务,是这样的吗?

    作者回复: 不同产品线如果领域模型差异太大的话,建议还是分开建设。这样不同产品之间的影响就很小了,也减少了很多兼容带来的开销,用户体验也不会太好。所以可以针对不同场景的产品设计出不同的微服务,但是在前端设计的时候需要注意,这些不同类产品的业务流程和前端界面是可以很好的融合在一起的。前端的设计我在后面也会有一节来讲解。注意一下,业务差异不是太大,不会带来太大复杂度的话,还是尽量建立一个领域模型。

    共 5 条评论
    13
  • 信了
    2020-10-22
    子域和限界上下文是什么关系?是包含吗

    作者回复: 我把书里面的内容直接贴过来吧。 学完第 5 章和本章后,有人可能会对子域与限界上下文的关系有些困惑。子域和限界上下文的映射关系到底是什么样的?一对多?或者多对一?还是一对一? 其实,在 DDD 中包括问题域和解决方案域两个不同的维度。问题域主要从业务视角来考虑,完成从领域到子域的分解,而解决方案域则主要从技术实现的角度,通过划分限界上下文和采用 DDD 战术设计完成微服务的拆分和落地。“子域”和“限界上下文”这两个概念分别从不同的视角,构建起了 DDD 处理业务复杂度的根基。 个人认为“子域”和“限界上下文”在大多数情况下是一对一或者一对多的映射关系。从实践角度可以这样理解,我们不妨将业务领域的分解拆分为两个阶段:从领域到子域的粗粒度的分解和从子域到限界上下文的技术实现级的分解。有时候企业的业务领域非常庞大,不太方便用事件风暴对整个领域构建领域模型。所以在领域建模之前,我们先根据业务流程边界或者功能集合等要素,将庞大的领域分解成若干个大小合适的子域,然后根据子域属性划分为核心子域、通用子域和支撑子域。当领域分解到足够小后,我们就可以在这些子域内开展事件风暴,划分限界上下文完成领域建模了。 在对不同属性子域构建领域模型时,我们可能会有不同的关注点,比如在通用子域构建领域模型时,我们会更多关注领域模型的抽象和标准化,以便实现企业级复用,这种设计方法与中台的业务建模思想是一致的。当然,如果你的领域足够小的话,我们就没必要进行从领域到子域的分解和属性归类了,你可以直接开展事件风暴,直接划分限界上下文,完成领域建模。按照这种分解方式,如果子域和限界上下文边界刚好一致,那它们就是一对一的关系,而如果在一个子域内还可以划分为多个限界上下文,那我们最终得到的就是一对多的映射关系。需要注意的是,有些通用子域构建出来的领域模型往往会因为需要复用,可能会跨多个不同的业务子域,组合以后形成企业级能力。 限界上下文本质上就是子域,只不过它会更多地考虑领域对象的语义边界和技术实现细节。限界上下文的划分体现的是一种更为详细的设计过程,这个过程划分了业务的上下文语义边界,完成了领域模型,明确了领域对象以及领域对象之间的依赖关系等。至此, 我们依据限界上下文和领域模型就可以完成微服务设计和落地了。

    共 3 条评论
    12
  • WING
    2019-10-21
    欧老师,文中提到“理赔子域就包括报案、查勘和定损等多个界限上下文(界限上下文与理赔的子子域边界重合)”这句话边界重合怎么理解?是否理赔应该作为一个微服务?另外,如果理赔流程在技术上引入了工作流引擎(如flowable),那么这个工作流引擎又处于什么位置?

    作者回复: 理赔相对保险领域来说是一个比较大的子域。由于子域过大不太容易做事件风暴,因此还需要继续细分子域。当子域细分到一定程度后,对这个子域的分析就比较容易了,很有可能这个子域就是一个限界上下文,所以这时候子子域的边界与限界上下文的边界是一致的。理赔不是一个微服务,需要根据不同子域事件风暴建立领域模型后,它其中的某个业务子域就是一个微服务,比如报案之类的。你说的这个工作流引擎是不是跨了很多的微服务,如果做统一协调,按照职能划分它应该是一个工作流微服务。另外,我简单分析一下,有的时候DDD的事件驱动可以替代工作流的功能,通过事件驱动推动业务在不同的领域模型中的流转。后面的章节会讲到。

    共 4 条评论
    10
  • 波波
    2019-10-18
    一、限界上下文的作用 1、主要是为了消除通用语言在不同领域中的歧义或者说是限制通用语言的使用范围。 2、是划分领域的重要依据 3、通用语言必须与限界上下文配合使用才有意义 二、限界上下文可以作为微服务拆分的重要依据
    展开

    作者回复: 是的。

    11
  • 瓜瓜
    2019-10-21
    我在拆分微服务的时候,一般是按照从属关系来划分的。 软件就是在表达这个世界的人和人的关系,人和物的关系,物和物之间的关系。他们之间的关系要么是从属,要么是分类。 在我之前的一个项目中,就遇到了这个给问题,他是一个人的对象,按照从属关系,他属于其中一个微服务,可是在实际操作中,发现它和我们的用户权限微服务关系更紧密。 没办法,只好把他从业务的微服务中移到用户权限的微服务中去了。 我想问问,在领域和子域的划分中,有没有非常明确的方法论没有。 我相信在业务的讨论中,不同人,从不同的角度看,我相信会有不同的划分区别。
    展开

    作者回复: 就我了解来说还没有量化的划分方法。主要依赖项目团队和领域专家的判断。 在事件风暴时候,子域不能太大,要不你hold不住。其实你说的那个人的问题,做微服务设计时会有一些技巧的,尤其是分布式架构下。如果一个对象同时存在于两个微服务中,你可以考虑一定的数据冗余。其中的一个微服务这个对象是主要的业务环节,它可以被设计为实体,而在另外一个微服务中这个数据是冗余数据,它可以设计为值对象或者关联实体。

    7
  • 南山
    2019-10-18
    老师,一直以为是先从业务来确定限界上下文,看完这篇有点疑惑, 1。限界上下文是通过细化到最后的子域的边界来决定的吗? 2。这些边界怎么组成一个完整的限界上下文呢()可以通过微服务落地的)? 3。软件是变化的,那限界上下文是不是也是会变化的呢?比如会根据这个变化来进行微服务拆分? 现在有n个微服务,除了组织架构这种支撑服务,其他的没法确定边界
    展开

    作者回复: 限界上下文是从业务端分析得出的。由于一般的领域过大,不太好下手去做事件风暴,所以在划分到合适的子域后做事件风暴就没那么复杂了。限界上下文是由若干个聚合构成的,聚合具有一定的业务内聚性。在依据限界上下文完成微服务设计后,以后还是可以很容易根据领域模型的变化来演进的。微服务演进过程主要是微服务之间聚合的重构。所以设计时要做好聚合的代码边界。

    共 2 条评论
    6
  • 乖,摸摸头
    2020-06-04
    看了好几章了,完全不清楚你在说啥,每一章都读了好几遍,我还有救吗?

    作者回复: 前面几章有些概念比较抽象,建议你结合后面的案例,再来理解前面的内容。

    共 2 条评论
    4
  • 谭方敏
    2020-02-21
    通用语言是限定领域内语义,而限界上下文就是限定领域边界,通用语言旨在扫清障碍,进行无差别沟通,老师的表格里面说的比较清晰了,就是大家达成共识的,统一的话术,限界上下文,有点类似Java中package或者C++的namespace的概念,包/名字空间里面可能有一个或者多个聚合,实体,值对象。

    作者回复: 是的。

    共 2 条评论
    4
  • 发飙的蜗牛
    2020-02-02
    老师,您好!说一下我的理解,我们是先划分子域,然后再基于这个子域去做事件风暴,然后在事件风暴过程中是有划分限界上下文这个步骤的,也就是说这个子域有可能会被划分为多个限界上下文,理论上也就是会对应多个微服务!但是会考虑其他因素,我们可能会将某几个上下文合并到一个微服务。那我是不是可以理解为在事件风暴中,一个子域也会被划分为多个子子域?因为在一开始我们可能并不知道我们应该这么划分,只有在事件风暴才知道应该这么划分。
    展开

    作者回复: 理解的没错。有时候并不一定需要将上下文拆分为微服务的,看企业的基础技术能力。如果没有这种能力还是尽量不要拆,等有这个能力的时候,你是可以很容易的拆分出微服务的。

    4
  • 观海雲遠
    2019-10-22
    你好,老师。 其实我很想知道当各个子域都确认了之后, 研发如何入手,从哪儿开始呢? 如何与敏捷中的故事卡结合。希望能有这方面的解答。 谢谢老师

    作者回复: 确定子域后,就可以做事件风暴了。事件风暴是一个领域建模的过程,实际上有一部分的工作是做用例分析,尽量全面的梳理业务的各种领域事件,找出实体、聚合等,根据业务语义划定限界上下文,建立领域模型,限界上下文是业务边界,也是微服务设计的边界。从领域模型到微服务还会有一个分析的过程。 微服务设计完成后,后面的开发方式就没什么区别了。

    共 3 条评论
    3
  • 嘉嘉☕
    2019-10-22
    老师好 拆到一定程度后,有些子子域的领域边界就可能变成限界上下文的边界了。 请问,怎样理解“一定程度”呢? “子子域的领域边界可能变成限界上下文的边界”,这句也不太好把握?
    展开

    作者回复: 你可以把限界上下文理解成一个子域。 限界上下文是在事件风暴后产生的,在找出实体和聚合后,会将聚合归拢到限界上下文,让他们在同一个业务语义环境下工作。这样多个聚合一起就组成了限界上下文,完成特定的业务领域的功能,这个限界上下文是不是就是一个子域呢?

    共 4 条评论
    3
  • 密码123456
    2019-10-21
    上节课说,域的划分。这节课说怎么划分。首先要对业务标准化,使用通用语言来描述,所有的业务,每个业务必须清晰不能存在二义性。这样就能确保业务流程转化为代码。然后使用界限上下文,确定每个业务的上限和下限,不多做,也不少做。比如请假事件,就不能直接使用加班的时长来抵扣。必须调用加班的接口

    作者回复: 理解的很对。在一个限界上下文就做这个限界上下文内的事情,请假就做请假的事,不要把加班的事情掺和进来。

    共 2 条评论
    3
  • 乖,摸摸头
    2020-06-04
    好嘛,我就想问,领域或者之前认为是模块 到底怎么划分的? 举个简单的例子,希望老师稍微指导一下,谢谢。 我们是做个信息对接平台的和58类似。用户分为 招聘方和求职方,招聘方发布招聘信息,求职方查看招聘信息。 求职方查看信息需要消耗积分,积分是通过充值或者拉新换来的(主要还是充值)。积分消耗主要是查看信息;以及置顶自己的信息。 招聘信息由招聘方发布,还有一部分是公司通过其他渠道获取的。 我做了个划分: 用户模块: 登录、注册 .... 信息模块: 招聘方发布、其他渠道获取 ,信息各种操作 ... 积分模块: 积分来源以及消耗记录,充值单价的设定 ... 这里我的疑问是,消耗、和获的 积分这个操作是放到 积分模块 还是用户模块。 如果 放到积分模块,需要修改用户剩余积分。 如果 放到用户模块,需要增加一条积分记录。
    展开

    作者回复: 从你描述的功能来看,这个场景主要包含三部分的关键功能。在进行领域划分的时候,你可以参考关键流程或功能集合。在你的场景里面,信息发布和查看属于比较关键的流程,而用户和积分则属于通用功能。所以在划分子域的时候,得到的结论跟你的描述是一致的。也就是划分为:用户、积分和信息管理三个子领域。当然每个子领域内部还需要用到后面的知识进行领域建模,找出领域模型中的对象,完成微服务设计。 初步可以判断用户这个子领域会有用户基本信息管理和用户登录认证两个聚合。 你说的消耗和获取积分是属于积分实体的业务行为,所以它们应该放在积分子域的聚合内,基于单一职责原则,积分聚合只完成积分相关的功能,积分聚合的聚合根是积分实体。用户只完成用户基本信息管理和登录认证功能,用户基本信息管理的聚合根是用户。 关于你的疑问:在积分聚合会有积分实体,在设计时,生成积分实体时会关联用户聚合根的用户ID,所以在积分聚合你可以根据用户ID查询该用户的积分实体,然后在积分聚合完成消耗积分的操作。 这只是一个大概的设计,后面还会有详细的领域建模和微服务设计方法。

    共 2 条评论
    2
  • 小藜
    2020-04-23
    老师好,是不是每个领域对应一个界限上下文,而每个子域有对应自己的界限上下文?界限上下文是否可以理解为领域的阈值?

    作者回复: 一个业务领域可以根据业务的语义边界划分为多个限界上下文,一个限界上下文建立一个领域模型,一个领域模型里面可能有多个聚合。

    2