文章目录
1 从哪里来到那里去
限界上下文从何而来,他不是一个从天而降的概念,一切都有迹可循。让我们回到现实世界思考。
1.1 问题空间与解空间
开发软件实际是要为用户解决现实中存在的某一类问题或为其带来某一领域的变革,在对用户问题进行分析及解决过程中我们划分了问题空间及解空间两个维度的空间。用通俗的描述问题空间是我们对现实世界问题的认识及描述,解决空间是对问题空间中问题的解决结果及方案。
从一个现实中的例子出发,比如需要砸一堵坚硬的墙,如何砸墙属于问题空间,而铁锤是该问题的一种解决方案属于解空间。
1.2 问题空间的来源
我归类我们行业问题空间来源于两个途径
- 解决痛点 :例如企业信息难以管理,企业受迫于信息化不健全,在进行企业信息时相当困难。
- 为用户带来变革 : 例如网购,购物等在网购出来前大家都习以为常,但网购的到来对人们购物方式发生了巨大的变革
1.3 对问题的拆分
很多时候大泥潭系统的产生并非开发过程不规范,而是在问题分析阶段就未认真对待,使得一个服务承担了一整个问题空间,所有的业务混杂一起,承载了太多的业务知识,开发人员理解起来难,开发起来更难。而将庞大复杂的大问题化为单一类似的小问题,这也是从源头上避免了大泥潭式系统。
分治算法给予了我们解决一个大问题的灵感,由大化小,并逐一击破。当我们在为客户开发一套系统解决客户领域内的问题时,也会形成复杂庞大的问题空间。若不对大问题进行拆分,一个完整的问题空间中,包含了各类复杂无序的业务规则,系统的开发效率及质量都将受到冲击,那么对大问题的拆分就很有必要了。
以一个门店管理系统的问题分析阶段为例,我们对其问题空间进行拆分,划分出以下问题域:
- 会员问题域 : 对门店会员管理上的问题;
- 财务问题域 : 门店进行财务营收统计上的问题;
- 营销问题域 : 门店商品推广上的问题;
- 员工问题域 : 门店的员工管理问题;
- 交易问题域 : 门店进行交易上的问题,是客户最希望解决的问题,为核心问题域;
我们重点关注该问题中的核心交易域,在交易问题域中我们进行了进一步的拆分得到了订单子域、结算子域、售后子域。对问题的拆分是无限制的,子问题可以被划分为更小的问题。
1.4 对问题的解决
拆分完毕问题空间,我们需要做到逐一击破,为每一个问题形成一套落地解决方案。一个问题对应一个答案,解空间与问题空间基本上应该是一一对应的。
我们给出的解方案是一个个限界上下文(图片简称BC),一个限界上下文负责应对其对应的问题进行解决,承载了该问题中的业务知识及规则。
2 限界上下文的作用
限界上下文是解决某一类问题的单一功能模块,例如订单限界上下文,处理开单、通知订单状态等一切与订单关联的功能,当前你可以理解为一个微服务,在之后我会解释其与一个服务有何区别。
2.1 统一语言的边界
随着问题的划分,将领域拆分成了不同的子域,每个子域有其独有的业务知识,而这些知识需要靠一门统一语言来描述。而不同限界上下文间的统一语言是相互独立的。可能在不同的限界上下文有同样的名词,但同样的名词在不同的限界上下文中可能表示的不是同一事物,即使是同一事物可能其在不同上下文中的关注点也不一致。
2.2 领域模型的边界
限界上下文是领域模型的边界,领域模型用限界上下文中的统一语言描述,领域模型是对现实业务的体现。
2.3 代码的边界
每一个限界上下文是一块独立的功能代码
3 子域、限界上下文、服务间的关系
对这三者间关系的提问是我遇到最多的,往往对限界上下文的不清晰来自与另外两部分的界限不清晰。
3.1 子域与限界上下文
子域是来自问题空间,而限界上下文相当于是对子域的回答。
3.2 限界上下文与服务
之前所说限界上下文是代码的边界,而其作为代码的边界可以有以下两种:
- 包、模块级别隔离
- 服务隔离级别
经常遇到有人将限界上下文与服务划等号,其实非也,两者可以说是毫无关联的,仅仅是第二种服务间隔离级别恰好一个服务等于一个限界上下文。
服务是运行部署的单位,而限界上下文是某一领域功能集合,一个限界上下文尽量保证与一个服务对应。但当项目发展初期,可以将多个限界上下文放于同一个服务中部署,只要严格遵守限界上下文间的集成规则,同样可以保证架构的清晰整洁。
在项目发展初期,交易服务内有订单上下文、结算上下文、售后上下文,当业务发展到一定规模后将这些上下文脱离成独立的服务。
关于限界上下文间的集成模式是相当关键的,将单独一文阐述。