跳到主要内容

边界与契约

模块边界定义变更时谁需要同步。好边界让团队并行;坏边界表现为「改一行牵十处」或「只能靠集成环境才发现 breakage」。

边界类型

类型载体契约形式典型失败
进程内模块包、target、namespace公开 API、禁止 deep import循环依赖
进程间HTTP/gRPCOpenAPI/Proto + 版本策略隐式字段、破坏性变更
异步消息、事件Schema registry、幂等键重复消费、乱序
数据DB、缓存迁移脚本、读写分离约定共享表直写

设计原则

  1. 按业务能力切,不按技术层切:「计费」「通知」优于「utils」「helpers」大包。
  2. 契约优先于实现:对外只承诺 schema 与语义;内部可重构。
  3. 防腐层(ACL):集成第三方或遗留系统时,在边界内翻译模型,禁止外部类型渗入领域。
  4. 失败隔离:超时、熔断、舱壁;默认值与降级策略写进文档。
注意

分布式单体:多个部署单元共享数据库且互相直写——表面是微服务,实际是紧耦合。优先「每服务自有存储 + 通过 API/事件协作」。

API 版本与兼容

策略适用做法
向后兼容扩展公共 REST/JSON只加可选字段;不改语义
显式版本多客户端、长生命周期/v1 路径或 header;旧版有下线日
事件版本消息流type + schemaVersion;消费者双读过渡

破坏性变更清单(需主版本或协调发布):

  • 删除或重命名字段、改类型
  • 改错误码语义、鉴权方式
  • 缩小可用枚举值

上下文映射(DDD 简表)

关系含义集成方式
共享内核同一模型子集共享库(谨慎,控制体积)
客户-供应商上游定 API,下游适配明确 SLA、契约测试
防腐层模型不兼容ACL 翻译
开放主机通用子域对外文档化公开 API
各行其道无集成不要假集成

契约测试(工程落地)

角色责任
提供者发布契约工件(Pact、OpenAPI snapshot)
消费者CI 拉取契约跑兼容性;失败阻塞合并
事件消费方对样例 payload 做契约测试

CI/CD 衔接:契约失败 = 与编译失败同级。

评审问题

  • 新依赖是否跨过边界 import 了「内部」包?
  • 超时、重试、幂等是否在边界两侧一致?
  • 错误模型是否稳定(机器可读 code + 人可读 message)?
  • 是否有「临时」共享 DTO 超过两个模块?

相关篇章