跳转到内容

上下文映射(Context Map)

用途:判断两个系统/团队之间该怎么集成、谁承担翻译成本时查阅

上下文映射是对各限界上下文之间关系类型与耦合方向的整体描述:不仅画出“谁调用谁”,还标注每一对关系采用哪种集成模式、由谁适配谁的模型。

它是战略设计的成果之一:限界上下文回答“边界在哪”,上下文映射回答“边界之间怎么相处”。

多个团队各自建模时,如果边界之间的关系不被显式管理,会自然退化成两种坏状态:要么共享一套模型(互相牵制、发布耦合),要么每对关系都临时协商(翻译规则散落在代码里,无人负责)。

Evans 提出用映射模式把这类关系命名化,使其成为可讨论、可评审的架构决策。

按上下游耦合程度排列,上游指被依赖方,下游指依赖方:

模式 关系约定 耦合 典型场景
大泥球(Big Ball of Mud) 边界模糊,模型互相渗透 极高 需要治理的历史状态,不是可选方案
共享内核(Shared Kernel) 两方共同维护一小块模型,变更需协同发布 高 同一产品线内确实同源的两块逻辑
遵奉模型(Conformist) 下游完全采用上游模型,不做转换 高 上游是不可控的外部标准或强平台方
客户-供应商(Customer-Supplier) 上游承诺响应下游需求 中 同一组织内的两个团队,有排期协作机制
防腐层(Anti-Corruption Layer, ACL) 下游建适配层,把上游模型翻译成本地模型 低 对接外部系统、遗留系统、第三方 SaaS
开放主机服务(Open Host Service, OHS) 上游以稳定协议对外提供服务 低 公共能力被多方消费
发布语言(Published Language) 交互使用明确定义的协议/Schema 低 与 OHS 搭配,也可用于跨组织交换
分离方式(Separate Ways) 明确不集成,各自独立 无 两块业务确实无必要互通,避免无谓耦合
联合上下文(Partnership) 两个上下文 jointly 规划演进节奏 中 必须同步发布的成对系统

三个问题决定模式选择:

  1. 上游可控吗? 不可控 → 遵奉模型或防腐层;可控且愿意配合 → 客户-供应商。
  2. 上游模型变化会不会污染本地核心模型? 会 → 必须加防腐层,哪怕多写一层转换。
  3. 两边是否必须一起发布? 是 → 联合上下文或共享内核(且要把共享范围压到最小)。

经验判断:新集成默认从防腐层起步,因为它保留了后续替换上游的能力;直接共享模型省下的成本,通常会在第一次上游改造时加倍偿还。

模式 工程形态
防腐层 独立适配器模块:外部客户端 + 转换器 + 本地模型;外部 DTO 不出适配层
开放主机服务 + 发布语言 对外 API 契约与事件 Schema 独立版本化(OpenAPI / Avro / Protobuf / JSON Schema),有兼容性策略
共享内核 单独发布的库,有共同负责人与联合发布流程;范围只含确实同源的最小模型
客户-供应商 需求排期机制 + 契约测试(消费者驱动契约)保障变更不破坏下游
上下文地图本身 一张标注关系类型的图,随代码版本维护;新集成必须先在图上登记

开源参考:Spring Cloud Contract、Pact(消费者驱动契约)、OpenAPI / AsyncAPI(发布语言)、ArchUnit(约束外部模型不侵入核心层)。

  • 限界上下文:映射描述上下文之间的关系,两者是同一套战略设计的两面。
  • 子域划分:通用域常以遵奉模型或 OHS 形式接入,核心域应处于映射的下游并被防腐层保护。
  • 集成模式:远程过程调用、事件驱动、共享数据库都是映射的技术承载方式;共享数据库通常意味着大泥球。
误区 修正
只画调用图不标关系类型 图上每条边标注模式与负责人
把防腐层写成字段改名工具 防腐层负责语义转换与规则隔离,不只是重命名
共享内核持续膨胀 定期审查,能移出的一律移出;共享范围以“是否需要一起发布”为限
对外部系统直接遵奉模型 外部模型进核心域后,更换供应商的成本会指数级上升
地图一次性交付 上下文地图必须跟代码同步演进,否则三个月后无人相信
  • Eric Evans《领域驱动设计》第 15 章(上下文映射,含全部模式原始表述)
  • Vaughn Vernon《实现领域驱动设计》第 10 章
  • Jimmy Bogard 关于防腐层与集成策略的公开文章系列