2. 用限界上下文划分采购与供应商管理边界
为什么采购与供应商管理不能塞进同一个上下文
在采购审批场景里,业务人员常说“供应商报价”“采购订单”“合同条款”,但同一个词在不同团队嘴里含义并不一致:采购员说的“合同”往往指采购订单的商务附件,法务说的“合同”是具备法律效力的框架协议,供应商管理员说的“供应商”是主数据实体,而采购员说的“供应商”可能只是本次询价的一个报价方。如果把这些概念强行放进一个模型,就会出现“供应商”既承载主数据又承载交易关系、“合同”既承载法律文本又承载订单行项的混乱。
限界上下文(Bounded Context)的作用,就是给这些含义不同的语言划出明确边界:在边界内,一个术语只有一个确定含义;跨边界时,通过上下文映射显式转换。划分依据不是模块大小,而是业务能力与语言一致性两个维度。
划分依据:业务能力与语言一致性
把采购与供应商相关能力先摊开,再判断哪些能力共享同一套语言:
- 供应商准入与主数据:供应商注册、资质审核、银行账户、联系人、黑名单。语言核心是“供应商作为可被长期引用的主体”。
- 寻源与报价:询价单、报价、比价、定标。语言核心是“一次采购活动中的候选方与报价”。
- 采购执行:采购申请、采购订单、收货、对账。语言核心是“订单行项与履约状态”。
- 合同管理:框架协议、条款、价格有效期、续签。语言核心是“具备法律约束力的文本与条款”。
其中“供应商”在准入上下文里是主数据实体,在寻源上下文里是报价参与方,在采购执行上下文里是订单的履约方。三者引用的是同一个现实对象,但关注的属性、生命周期和一致性要求完全不同,因此应拆分为不同上下文,而不是共用一个“供应商”聚合。
判断口诀:同一术语在两组能力中若“标识相同但属性集与生命周期不同”,就应拆分为两个上下文,并在映射中约定引用方式(通常用 ID 引用而非对象嵌套)。
上下文映射关系
拆分后需要明确上下文之间的协作方向与集成模式。下面这张图给出本例的划分结果与映射关系:供应商管理作为上游主数据源,寻源与采购执行作为下游消费方;合同管理独立成上下文,向采购执行提供条款约束。
映射关系说明与集成约定
图中四条映射关系对应四种集成约定,落地时需要明确引用方式与一致性策略:
| 上游上下文 | 下游上下文 | 映射模式 | 传递内容 | 一致性策略 |
|---|---|---|---|---|
| 供应商管理 | 寻源与报价 | 客户/供应商 | 供应商ID、名称、资质状态 | 下游只读引用,不修改主数据 |
| 供应商管理 | 采购执行 | 客户/供应商 | 供应商ID、资质快照 | 下单时校验资质有效性 |
| 寻源与报价 | 采购执行 | 定标结果传递 | 中标供应商ID、报价明细 | 定标事件驱动,异步通知 |
| 合同管理 | 采购执行 | 条款约束 | 合同ID、价格有效期、条款 | 下单时校验价格是否在有效期内 |
关键约定:跨上下文一律使用 ID 引用,禁止对象嵌套。采购执行上下文中的“供应商”只保存 supplierId 与下单时快照的资质状态,不复制供应商主数据;合同条款通过 contractId 引用,价格校验在采购执行侧完成。
验证划分是否合理
划分完成后,用以下三个问题自检:
- 语言是否一致:在采购执行上下文内,所有团队提到“供应商”时是否都指“订单履约方”?如果还有人指主数据,说明边界没划清。
- 变更是否隔离:供应商资质审核规则变化时,是否只需改供应商管理上下文,而不影响采购订单模型?
- 映射是否显式:跨上下文的数据传递是否都有明确的 ID 引用和一致性策略,而不是隐式共享数据库表?
若三个问题都能给出肯定回答,说明采购与供应商管理的限界上下文划分达到了可落地的程度。