Skip to content

Shared Kernel(共享内核) ​

解决什么问题:多个 BC 共享一组核心概念(如 UserId / Money / TenantId)——重复定义会导致类型不兼容和翻译成本——Shared Kernel 让多个 BC 共享一部分代码/模型,但必须联合管理避免单方修改。

它是什么 ​

Shared Kernel 是 Vernon 9 种 BC 关系之一——两个或多个 BC 共享一个共同的内核(代码库 / 模型):

  • 共享内容:类型定义(UserId、Money)、基础值对象、枚举、常量
  • 联合管理:任何一方修改必须通知其他方(共同决策)
  • 同步发布:所有使用方同时升级到新版本
  • 编译时共享:通常是同一代码库 / 同一 Maven 模块 / 同一 npm 包

Vernon Ch 3: "Two teams agree to share a subset of the domain model. They agree on the parts that they will share." "Explicitly designate which classes belong to the Shared Kernel and create a process for keeping that kernel small and free of contention."

V2 视角(V2 B3 分解的反向):Shared Kernel = 主动承认某些部分无法独立分解——把不可避免的耦合显式化、集中管理。

关键属性 ​

属性值/含义
共享内容类型定义 + 基础值对象 + 常量(不包含业务逻辑)
范围2-3 个 BC(超过 3 = 拆分失败)
管理方式联合所有方共同决策 + 同步发布
变更流程修改前必须通知所有使用方 → 决策 → 同步升级
版本控制SemVer 严格遵守(破坏性改动 = MAJOR bump)
反模式共享业务逻辑 / 共享 Repository / 共享数据库
核心约束共享内核必须保持小——超过 10 个类 = 拆分失败

怎么用 ​

场景 1:识别 Shared Kernel 候选 ​

识别标准:

  1. 两个 BC 都使用相同的基础类型(UserId / TenantId / Money)
  2. 这些类型没有业务逻辑(只是标识符或值对象)
  3. 翻译成本高——每个 BC 自己定义 UserId,会导致类型不兼容
  4. 修改频率低——共享内核要稳定

典型共享内容:

  • ID 类型(UserId / OrderId / TenantId)
  • 通用值对象(Money / Address / TimeRange)
  • 枚举(Status / Currency)
  • 常量(错误码 / 业务规则编号)

场景 2:Shared Kernel 实现(独立包) ​

shared-kernel/
├── src/
│   ├── ids/
│   │   ├── UserId.ts
│   │   ├── OrderId.ts
│   │   └── TenantId.ts
│   ├── values/
│   │   ├── Money.ts
│   │   └── Address.ts
│   └── constants/
│       └── error-codes.ts
├── package.json       (SemVer 严格管理)
└── CHANGELOG.md       (破坏性改动明确标记)

版本管理:

  • v1.0.0 → v1.1.0 = 加方法(向后兼容)
  • v1.1.0 → v2.0.0 = 破坏性改动(所有 BC 同步升级)

场景 3:修改流程(联合决策) ​

修改 Shared Kernel 的标准流程:

  1. 提出变更:任何一方提 PR 到 Shared Kernel 仓库
  2. 通知所有使用方:邮件 + Slack + 团队会议
  3. 评审:所有相关团队必须参与 PR 评审
  4. 决策:共识通过 → 合并;不通过 → 拒绝或延后
  5. 同步升级:发布新版本 → 所有 BC 同步升级 → 同步部署
  6. 回滚预案:如有 BC 无法升级,必须先协调后再发布

场景 4:Shared Kernel 与其他关系的区别 ​

维度Shared KernelCustomer-SupplierPublished Language
耦合度高(共同代码)中(API 调用)低(标准数据格式)
变更成本高(所有方同步)中(下游适配)低(按版本迁移)
灵活性低(受共同代码约束)中(上下游独立演化)高(PL 仅约束数据格式)
适用共享基础类型上下游清晰多客户跨组织

常见误区 ​

  1. "Shared Kernel = 共享所有代码"——错。Shared Kernel 越小越好。共享业务逻辑 = 应该合并 BC
  2. "Shared Kernel 包含 Repository"——错。Repository 是聚合根的持久化抽象,是 BC 私有。共享 = 暴露 BC 内部细节
  3. "Shared Kernel 包含数据库表"——错。共享数据库 = 失去 BC 自治(V2 B3 分解的目标)
  4. "单方任意修改"——错。联合管理是核心。任意修改 = 其他 BC 无声破坏
  5. "Shared Kernel 越长越大"——错。超过 10 个类 = 拆分失败——应该合并 BC 或拆出独立工具库(Generic Subdomain)
  6. "Shared Kernel = Customer-Supplier"——错。Shared Kernel 是共同代码,C-S 是调用关系。前者编译时耦合,后者运行时耦合

关键洞察 ​

Shared Kernel = "主动受控的耦合"——承认有些部分无法独立分解,把耦合显式化。

何时选 Shared Kernel:

  • 共享基础类型(UserId 等)— 不可避免
  • 共享类型稳定(修改频率低)
  • 使用方有能力联合管理(团队协作良好)

何时不选 Shared Kernel:

  • 共享业务逻辑 → 合并 BC
  • 共享 Repository / 数据库 → 拆分 BC 边界
  • 共享类型快速演化 → 用 Published Language 替代
  • 使用方无法联合管理 → 避免 Shared Kernel

这是 V2 B3 分解的反向工程化——分解失败时不要硬拆,集中管理反而更好。

判断 Shared Kernel 是否健康 = 内核 ≤ 10 个类 + 修改频率 ≤ 1次/季度 + 所有使用方同步升级。 判断失败 = 内核不断膨胀 + 频繁破坏性改动 + 团队抱怨耦合。

相关链接 ​

从名家方法论与工程化思路中蒸馏出自己的工程体系。