加载中...

本篇要搞懂的 2 个概念:通用语言(Ubiquitous Language)、限界上下文(Bounded Context)。

DDD 在解决一个很现实的问题:项目里产品、开发、测试、业务专家怎么说同一种"语言"?

不解决会怎样:

  • 产品文档里叫"用户"、代码里叫 Account、业务部门叫"客户"——三套叫法、翻译损耗大。
  • 同一个"订单",销售说成交记录、物流说配送任务——开会鸡同鸭讲。

DDD 用两个概念来解:通用语言约定"说什么",限界上下文圈定"在哪里有效"。

承接上一讲:02 讲拆完了领域 → 子域 → 子子域,回答了"业务范围有多大、哪块重要"。03 讲要回答"拆到的最小单元里用什么语言、模型在哪里生效"。

通用语言:团队的"行话"

通用语言 = 项目团队约定好的统一词汇表。所有角色(领域专家、产品、架构师、开发、测试)在同一个领域内都用这套词。

它的内容分两类,直接对应到代码

通用语言里的元素 在代码中对应 例子
名词 领域对象(实体、值对象) 商品、订单、用户
动词 / 事件 领域事件、命令 商品已下单、订单已付款

价值:让业务模型和代码模型保持一一映射——业务人员能在代码里直接定位实现,开发人员能在沟通里听懂业务原话。

通用语言贯穿从事件风暴到代码落地的整个过程

一个实用经验:领域对象映射表

设计过程中,用一张表把所有领域对象记下来——名字、属性、依赖关系、所在的 DDD 分层、对应的代码对象。这张表本身就是项目团队的通用语言字典。

领域对象与代码对象的映射表样例

这张表的价值:

  • 团队内部沟通有统一口径,不再"产品说 A、开发说 B"。
  • 开发可以按表直接落地代码,不需要二次翻译。
  • 业务人员看到字段名也能找到代码位置,方便后续维护。

限界上下文:行话生效的"地盘"

通用语言不可能在整个公司全局生效——同一个词在不同场景下意思不同。这就需要给词划"地盘",地盘内含义唯一。这个地盘就是限界上下文

限界 = 边界,上下文 = 语义环境。 边界内通用语言有唯一含义,边界外重新解释。

经典语义例子:能穿多少就穿多少

孩子问妈妈:“今天该穿几件?” 妈妈答:“能穿多少就穿多少。”

  • 寒冬腊月的上下文里 → 穿厚一点
  • 炎炎夏日的上下文里 → 穿少一点

同一句话,意思完全相反——因为语义环境不同。

业务也是同理:一个词不能脱离上下文存在。

一个比保险更直观的例子:学校里的"老师"

上下文 "老师"是什么 关心的属性
教务系统 讲课的人 教龄、学科、班级、课表
人事系统 一个雇员 工号、薪资、社保、考勤
食堂系统 持卡就餐者 卡号、余额、优惠等级

三个上下文里都有"老师",每个都对,但模型完全不一样

  • 不分上下文:建一张"老师表"塞所有字段——上帝表,谁改谁懵。
  • 分了上下文:教务、HR、食堂各自维护各自的"老师模型",互不干扰——正好对应 3 个微服务

保险领域的例子:同一份合同的四副面孔

文章里"投保单 → 保单 → 批单 → 赔案"的本意是:同一份保险合同,在不同业务流程里变成不同的领域对象

业务环节 合同叫什么 关心什么
客户填信息、还没生效 投保单 申请信息、待缴费状态
付完钱、合同正式生效 保单 生效日期、保额、被保人
客户中途要改信息 批单 变更项、生效时间
客户出事要理赔 赔案 出险信息、理赔金额

为什么不用一个"保单"贯穿全流程?

  • 一个对象塞所有字段 → 几十上百个字段,难以维护。
  • 投保流程改动会牵动理赔代码 → 团队互相干扰。

划成 4 个限界上下文之后:每个上下文有自己的领域模型、自己的通用语言、自己的演进节奏——正好就是 4 个微服务

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

第一步:先理清层级关系

把保险业务这个领域,按 02 讲的思路一层层切:

领域:整个保险业务            (巨大)
   ↓ 切第一刀
子域:投保 / 支付 / 保单 / 理赔  (中等)
   ↓ 切第二刀(不一定要切)
子子域:报案 / 查勘 / 定损       (小)
   ↓ 切到底
限界上下文                      (最小,落地为代码)

保险领域中子域与限界上下文的层级关系

关键点:不是所有子域都需要切到底

  • 有的子域本身就够小、足够独立 → 这个子域自己就是一个限界上下文
  • 有的子域内部业务复杂 → 这个子域里要包含多个限界上下文

第二步:为什么有时子域 = 限界上下文,有时不是?

判断标准:这块业务里的"语言"是不是从头到尾统一

例子 A:投保子域(整个子域 = 1 个限界上下文)

整个流程就是「客户填信息 → 系统记录 → 等付款」。"投保单"这个词从头用到尾,含义一致。所以投保子域本身就是一个限界上下文,对应一个微服务

例子 B:理赔子域(一个子域 = 3 个限界上下文)

里面流程分好几步,每步关心的东西完全不同:

步骤 谁在干 关心什么 模型叫什么
报案 客户打电话 出事了、时间、地点 报案单
查勘 理赔员到现场 事故是否真实、责任分配 查勘单
定损 评估师 损失值多少钱 定损单

虽然都和"理赔"有关,但每一步的语言和模型完全不同——所以要把理赔子域切成 3 个限界上下文,对应 3 个微服务

第三步:为什么"限界上下文 ≈ 微服务"?

这不是数学等式,而是"长得像"。把两者要求对一下:

限界上下文具备的特征 微服务的设计目标
一套独立的词汇表(通用语言) 接口清晰、契约明确
一组紧密相关的对象(领域模型) 高内聚
内部业务自洽、外部依赖少 低耦合
内部改动不影响外部 独立演进、独立部署

两者要求几乎一模一样。所以拿限界上下文当微服务边界,是最自然的选择——不用再额外想"微服务到底拆到哪",限界上下文画到哪,微服务就拆到哪。

第四步:为什么实践中不是严格 1:1?

理论说 1:1,实践要看现实约束:

现实约束 实际怎么处理
团队太小(3 个上下文只有 3 个开发) 合并成 1 个微服务,省运维
性能要求(A、B 之间调用极其频繁) 合成 1 个微服务,省网络开销
技术异构(一部分必须 Python,一部分必须 Go) 即使可以合并也必须拆开
业务变化频率不同 变化频繁的拎出来单独迭代

所以:理论上 1:1 是理想,实践上 1:1 是教条

一句话收束

限界上下文是"业务视角的边界",微服务是"系统视角的边界"。
业务边界画清楚了,系统边界自然就有了——但要不要严格对齐,看团队和技术现实。

总结

通用语言是项目团队在事件风暴中达成共识、贯穿设计与代码全过程的统一词汇表。它由两类元素构成——名词对应实体和值对象,动词对应领域事件和命令,并通过"领域对象映射表"与代码模型一一对应。它的核心价值是消除翻译损耗:领域专家、产品、开发、测试用同一套词沟通,业务模型和代码模型保持一致,业务人员能在代码里直接定位实现,开发也能听懂业务原话。

限界上下文是通用语言生效的边界——边界内术语含义唯一,边界外要重新解释。它通过给词划"地盘",解决两件事:一是避免同一个词在不同业务场景下产生歧义;二是把臃肿的"上帝模型"拆成职责单一的领域模型,让团队能独立演进各自的上下文。划分限界上下文的关键线索,是抓住业务流程中的"状态变化点"和"词的歧义点"。

限界上下文 ≈ 微服务。一个限界上下文 = 一套独立的通用语言 + 一组紧密相关的领域对象,刚好满足微服务"高内聚、低耦合"的要求。理论上把限界上下文里的领域模型映射到代码,就完成了从问题域到解决方案的落地。但实践中要结合团队规模、技术异构、性能要求等做适度调整,1:1 是理想、不是教条

先把"是什么"回答清楚

概念 官方定义(DDD 标准说法) 一句话大白话 例子
通用语言(Ubiquitous Language) 团队在事件风暴中达成共识、能简单清晰准确描述业务含义和规则的统一语言,贯穿设计、文档、代码全过程 团队的"行话" “工单”“下单”“付款”
限界上下文(Bounded Context) 用来封装通用语言和领域对象、提供语义环境的领域边界;边界内术语含义唯一 行话生效的"地盘" 教务上下文 vs HR 上下文里的"老师"

两者的关系:通用语言不能脱离限界上下文存在——离了上下文,词就有歧义。

再讲"为什么要这么搞"

解决的问题 怎么解决
同一个词在不同场景含义不同 → 歧义 限界上下文圈定语义边界
业务模型臃肿(上帝对象) 一个上下文一份模型,模型职责单一
团队互相干扰、改动牵连 上下文隔离,各自独立演进
微服务该拆到哪 限界上下文 ≈ 微服务边界

一句话速记

通用语言是团队的"行话",限界上下文是行话生效的"地盘"。地盘划好了,微服务边界也就划好了。

怎么找到你的限界上下文?(落地建议)

  1. 办一次事件风暴:拉上业务专家、产品、开发,把业务流程上的所有"动作 / 事件 / 实体"贴满白板。
  2. 找词的"歧义点":同一个词在不同人嘴里含义不同时,那就是上下文边界的提示。
  3. 找业务流程的"状态转换点":比如"投保单"变"保单"——状态变名字也变,往往跨了上下文。
  4. 整理领域对象映射表:把每个上下文内的实体、值对象、事件列清楚,并和代码对象一一映射。
  5. 限界上下文 → 微服务:理论上 1:1,实践中结合团队规模、技术约束做适度调整。

思考题

回到你目前的项目:

  • 哪些词在团队里有歧义?(产品和开发各说各的那种)
  • 这些歧义对应到业务流程里,能不能找到天然的"状态切换点"?
  • 如果按这些切换点划分限界上下文,会和现在的微服务边界一致吗?
公告栏
这是我的个人知识库。
记录技术,也记录生活 —— 读过的、试过的、想明白的,都堆在这儿。
最新文章
网站资讯
文章数目 :
5
已运行时间 :
本站总字数 :
15.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
全局知识图谱
当前页面 已访问 文章 标签
ESC 关闭 · 滚轮缩放 · 拖拽移动 · Ctrl+G 开关