惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
AI
AI
Recent Announcements
Recent Announcements
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
J
Java Code Geeks
TaoSecurity Blog
TaoSecurity Blog
L
LangChain Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
Microsoft Security Blog
Microsoft Security Blog
量子位
T
Threatpost
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - Franky
博客园 - 聂微东
L
LINUX DO - 最新话题
Security Archives - TechRepublic
Security Archives - TechRepublic
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
C
Check Point Blog
宝玉的分享
宝玉的分享
G
Google Developers Blog
Spread Privacy
Spread Privacy
Cloudbric
Cloudbric
SecWiki News
SecWiki News
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
V
Vulnerabilities – Threatpost
Cyberwarzone
Cyberwarzone
A
Arctic Wolf
P
Privacy & Cybersecurity Law Blog
P
Palo Alto Networks Blog
H
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
A
About on SuperTechFans
N
Netflix TechBlog - Medium
罗磊的独立博客
月光博客
月光博客

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计 【系统架构设计】数据迁移与版本化:在线不停机的数据演进 【系统架构设计】数据湖与数据仓库:分析架构的演进路线 【系统架构设计】API 网关设计:入口层的职责边界 【系统架构设计】应用层数据一致性模式:在正确性与性能之间走钢丝 【系统架构设计】多模数据库选型:Polyglot Persistence 的工程实践 【系统架构设计】服务发现与注册:动态拓扑的基础设施 【系统架构设计】配置管理架构:从配置文件到配置中心 【系统架构设计】全链路压测:大规模系统的性能验证 【系统架构设计】幂等性设计:分布式环境下的安全重试 【系统架构设计】契约测试与 Schema 演进:服务间的信任协议 【系统架构设计】长连接与推送架构:WebSocket、SSE 与 MQTT 【系统架构设计】延迟分析:从 P50 到 P999 的全链路追踪 【系统架构设计百科】DDD 战术模式:聚合、实体与值对象 【系统架构设计百科】防腐层与开放主机服务:系统集成的 DDD 方案 【系统架构设计百科】领域事件与事件风暴:从业务到架构的桥梁 【系统架构设计百科】CQRS + Event Sourcing 完整实战:从领域建模到部署 【系统架构设计百科】DDD 与微服务:用领域模型划分服务边界 【系统架构设计百科】认证架构:从 Session 到 JWT 到 OIDC 【系统架构设计】API 设计哲学:REST vs GraphQL vs gRPC 的真实权衡 排序算法专题:从 TimSort 到并行排序 【密码学百科】国密算法体系:SM2/SM3/SM4/SM9 全景解读 【密码学百科】承诺方案:Pedersen 承诺、向量承诺与多项式承诺 【密码学百科】不经意传输与隐私信息检索:OT、OT 扩展与 PIR 【密码学百科】门限密码学:门限签名、门限解密与分布式密钥生成 完美哈希:从理论到 gperf 实践 【密码学百科】安全多方计算:从 Yao 的混淆电路到实用 MPC 【密码学百科】同态加密:从 Paillier 到全同态加密(FHE) 【密码学百科】零知识证明系统:zk-SNARKs、zk-STARKs 与 Bulletproofs 【密码学百科】概率论与密码分析:生日攻击、差分分析与线性分析 【密码学百科】计算复杂性与归约:密码安全性证明的基石 【密码学百科】秘密共享:Shamir 方案、VSS 与安全多方计算入口 【密码学百科】椭圆曲线代数:Weierstrass 方程、点群运算与曲线选择 【密码学百科】离散对数与配对密码学:从 DLP 到 BLS 签名 【密码学百科】格密码数学基础:SVP、LWE 与格基约化 【密码学百科】抽象代数:群、环、域的密码学视角 【密码学百科】有限域算术:GF(2^n) 运算与在 AES/ECC 中的应用 【密码学百科】数论进阶:二次剩余、椭圆曲线上的 Weil 配对 【密码学百科】密码学简史:从凯撒密码到量子时代 【密码学百科】威胁模型与安全目标:CIA 三要素之外 【密码学百科】Kerckhoffs 原则与现代密码设计哲学 【密码学百科】随机性:密码学的基石 【密码学百科】信息论入门:熵、完美保密与 Shannon 定理 【密码学百科】分组密码原理:Feistel 网络与 SPN 结构 【密码学百科】AES 逐步拆解:SubBytes 到 MixColumns 的数学 【密码学百科】分组密码工作模式全览:ECB/CBC/CTR/OFB/CFB 【密码学百科】流密码:RC4 的兴衰与 ChaCha20 的崛起 【密码学百科】密码学哈希函数:MD5→SHA-2→SHA-3 的进化之路 【密码学百科】MAC 与 HMAC:消息认证的正确姿势 【密码学百科】认证加密(AEAD):GCM、ChaCha20-Poly1305 与 OCB 【密码学百科】密钥派生函数:HKDF、PBKDF2、Argon2 与密码存储 【密码学百科】公钥密码的数论基础:模运算、群、原根 【密码学百科】RSA 从原理到攻击:教科书 RSA 为什么不安全 【密码学百科】Diffie-Hellman 密钥交换与离散对数问题 【密码学百科】椭圆曲线密码学(ECC):从几何直觉到点群运算 【密码学百科】数字签名:ECDSA、EdDSA 与 Schnorr 签名 【密码学百科】现代密钥交换:X25519、ECDHE 与前向保密 【密码学百科】混合加密与 KEM/DEM 范式:ECIES 与 HPKE 【密码学百科】填充方案:PKCS#1 v1.5、OAEP 与 PSS 【密码学百科】TLS 协议全解析:从握手到 0-RTT 【密码学百科】PKI 与数字证书:信任链的构建与崩塌 【密码学百科】密码认证协议:从 SRP 到 OPAQUE 【密码学百科】零知识证明入门:如何证明你知道而不泄露 【密码学百科】安全信道构造:Noise 协议框架与 Signal 协议 【密码学百科】密钥管理工程:HSM、KMS 与密钥生命周期 【密码学百科】侧信道攻击:从时序攻击到功耗分析 【密码学百科】密码学实现陷阱:三层漏洞分类、审计工具链与系统性预防 密码敏捷性:如何设计可升级的密码系统 【密码学百科】OpenSSL/BoringSSL 架构剖析:ENGINE、Provider 与 FIPS 模块 【Linux 网络子系统深度拆解】内核网络调优方法论:从基准测试到生产验证 排序基准测试:用数据说话
【系统架构设计】DDD 战略设计:限界上下文与上下文映射
2026-04-13 · via 土法炼钢兴趣小组的算法知识备份

一个中型电商系统里,“订单”在交易团队意味着”待支付的购物车快照”,在物流团队意味着”等待拣货的配送单”,在财务团队意味着”一条应收账款记录”。三个团队共用同一张 t_order 表、同一个 OrderService 类,每次迭代都互相踩脚。这种混乱的根源不是代码质量,而是缺少一项最基本的架构决策——限界上下文(Bounded Context) 的划分。

Eric Evans 在 2003 年出版的《领域驱动设计》一书中首次系统化地提出了战略设计(Strategic Design)的概念。二十多年后,这些概念依然是大型系统架构的基石。本文将从限界上下文的本质出发,深入解析上下文映射(Context Mapping)的 9 种模式,并给出可落地的决策框架。

上一篇:推送架构 | 下一篇:DDD 战术模式


一、限界上下文的本质

1.1 它不是”微服务边界”

在当今的技术社区中,限界上下文常被简单等同于”一个微服务”。这种理解只抓住了表象。Evans 原著中对限界上下文的定义是:

A Bounded Context is a boundary within which a particular model is defined and applicable.

核心要素有三个:

  1. 模型(Model):一组概念、关系和规则的集合;
  2. 语言(Ubiquitous Language):团队在该上下文内对概念的统一命名和理解;
  3. 边界(Boundary):模型和语言的适用范围。

限界上下文首先是一个语义边界,而不是一个部署单元。一个限界上下文可以对应一个微服务,也可以对应一个单体中的模块,甚至可以对应一个第三方系统。

1.2 通用语言:上下文的灵魂

通用语言(Ubiquitous Language)是限界上下文的核心驱动力。在同一个上下文内,所有人——开发者、产品经理、领域专家——必须使用完全相同的术语来描述同一个概念。

上下文:交易域
  "订单" = 用户提交的一次购买意图,包含商品快照、价格、优惠信息
  "下单" = 创建订单的行为
  "取消" = 用户主动放弃未支付订单

上下文:物流域
  "订单" = 一条等待拣货和配送的指令
  "下单" = 物流系统接收到配送请求
  "取消" = 配送中止,触发退货流程

同一个词”订单”在不同上下文中有不同含义,这不是问题——这正是限界上下文存在的意义。问题在于把两种含义混在同一个模型里。

1.3 上下文边界的识别信号

以下信号通常意味着你需要拆分上下文:

信号 说明
同一术语在不同团队有不同含义 “订单”在交易和物流中语义不同
一个实体承担过多职责 User 类同时包含认证、画像、社交属性
修改一个功能需要协调多个团队 改价格逻辑需要交易和促销团队同时参与
数据模型中出现大量可选字段 不同场景只用到部分字段
业务规则互相矛盾 交易域要求”订单不可修改”,客服域要求”订单可修改”

二、Evans 的核心概念重新解读

2.1 领域与子域

在 Evans 的体系中,领域(Domain)是整个业务问题空间,子域(Subdomain)是其自然划分。子域有三种类型:

┌──────────────────────────────────────────────┐
│                  业务领域                      │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │ 核心子域  │  │ 支撑子域  │  │ 通用子域  │   │
│  │ Core     │  │Supporting│  │ Generic  │   │
│  │          │  │          │  │          │   │
│  │ 竞争优势  │  │ 必要但非  │  │ 标准化   │   │
│  │ 需要深度  │  │ 核心差异  │  │ 可外购   │   │
│  │ 领域建模  │  │ 化能力   │  │ 或复用   │   │
│  └──────────┘  └──────────┘  └──────────┘   │
└──────────────────────────────────────────────┘
  • 核心子域(Core Subdomain):企业的竞争优势所在,值得投入最好的团队和最深的建模;
  • 支撑子域(Supporting Subdomain):业务必需但不构成差异化竞争力;
  • 通用子域(Generic Subdomain):认证、通知、日志等标准化能力。

2.2 子域与限界上下文的关系

子域是问题空间的划分,限界上下文是解决方案空间的划分。二者的关系不是简单的一对一:

关系 场景
一个子域 → 一个上下文 理想情况
一个子域 → 多个上下文 子域复杂度高,需要进一步拆分
多个子域 → 一个上下文 遗留系统,子域边界模糊

2.3 限界上下文的内部结构

一个限界上下文内部通常包含:

┌─────────────────────────────────────┐
│        限界上下文(Bounded Context)  │
│                                     │
│  ┌───────────┐  ┌───────────┐      │
│  │ 领域层     │  │ 应用层    │       │
│  │ - 聚合    │  │ - 应用服务 │      │
│  │ - 实体    │  │ - 命令处理 │      │
│  │ - 值对象  │  │ - 查询处理 │      │
│  │ - 领域服务│  │           │       │
│  │ - 领域事件│  │           │       │
│  └───────────┘  └───────────┘      │
│                                     │
│  ┌───────────┐  ┌───────────┐      │
│  │ 基础设施层 │  │ 接口层    │       │
│  │ - 仓储实现│  │ - API     │      │
│  │ - 消息发布│  │ - 事件消费 │      │
│  │ - 持久化  │  │ - 转换器  │       │
│  └───────────┘  └───────────┘      │
└─────────────────────────────────────┘

三、上下文映射的 9 种模式

上下文映射(Context Mapping)描述的是两个限界上下文之间的关系。这种关系既包含技术层面的集成方式,也包含组织层面的团队协作模式。

3.1 全景图

graph TB
    subgraph "上下文映射模式"
        SK["共享内核<br/>Shared Kernel"]
        CS["客户-供应商<br/>Customer-Supplier"]
        CF["遵从者<br/>Conformist"]
        ACL["防腐层<br/>Anti-Corruption Layer"]
        OHS["开放主机服务<br/>Open Host Service"]
        PL["发布语言<br/>Published Language"]
        PT["合作关系<br/>Partnership"]
        SW["各行其道<br/>Separate Ways"]
        BBM["大泥球<br/>Big Ball of Mud"]
    end

    subgraph "按团队协作分类"
        direction TB
        M1["互利对等"] --> PT
        M1 --> SK
        M2["上下游依赖"] --> CS
        M2 --> CF
        M2 --> ACL
        M3["公共接口"] --> OHS
        M3 --> PL
        M4["无协作"] --> SW
        M4 --> BBM
    end

3.2 共享内核(Shared Kernel)

两个上下文共享一小部分模型(代码、数据库 schema 或消息格式)。

  • 适用场景:两个密切协作的团队需要共享核心领域概念;
  • 组织前提:团队之间信任度高,修改共享部分需要双方同意;
  • 风险:共享部分越大,耦合越深;任何修改都可能影响两个上下文。
// shared-kernel 模块:两个上下文都依赖
package com.example.shared.kernel;

public class Money {
    private final BigDecimal amount;
    private final Currency currency;

    public Money(BigDecimal amount, Currency currency) {
        if (amount == null || currency == null) {
            throw new IllegalArgumentException("金额和币种不能为空");
        }
        this.amount = amount;
        this.currency = currency;
    }

    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("币种不一致,无法直接相加");
        }
        return new Money(this.amount.add(other.amount), this.currency);
    }

    // equals 和 hashCode 基于值比较
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Money)) return false;
        Money money = (Money) o;
        return amount.compareTo(money.amount) == 0
            && currency.equals(money.currency);
    }
}

3.3 客户-供应商(Customer-Supplier)

上游上下文是供应商,下游上下文是客户。下游的需求会影响上游的优先级。

  • 适用场景:两个团队有明确的上下游关系,下游能影响上游的路线图;
  • 组织前提:上游团队愿意倾听下游需求并调整接口;
  • 典型例子:订单上下文(上游)为物流上下文(下游)提供订单数据。
上游(订单)                    下游(物流)
┌───────────┐   需求反馈   ┌───────────┐
│ OrderService│ ←────────── │ ShippingService│
│           │   提供 API   │           │
│           │ ──────────→  │           │
└───────────┘              └───────────┘

3.4 遵从者(Conformist)

下游上下文完全接受上游的模型,不做任何转换。

  • 适用场景:上游是强势的第三方系统或组织标准,下游没有谈判余地;
  • 组织前提:下游团队接受上游模型对自身领域模型的”入侵”;
  • 风险:下游的领域模型被上游污染,业务语义可能被扭曲。

3.5 防腐层(Anti-Corruption Layer)

下游在自己与上游之间建立一个翻译层,将上游模型转换为自己的领域模型。

  • 适用场景:需要对接遗留系统或外部系统,但不希望被其模型污染;
  • 组织前提:下游有能力和意愿投入资源建设翻译层;
  • 实现方式:Facade + Adapter + Translator 三层结构。
// 防腐层示例:将遗留 ERP 的订单模型转换为本域模型
type ERPOrder struct {
    OrdNo     string  `json:"ord_no"`
    CustCode  string  `json:"cust_code"`
    TotalAmt  float64 `json:"total_amt"`
    StatusFlg int     `json:"status_flg"`
}

type DomainOrder struct {
    OrderID    OrderID
    CustomerID CustomerID
    Total      Money
    Status     OrderStatus
}

// Translator:负责模型转换
func translateERPOrder(erp ERPOrder) (DomainOrder, error) {
    status, err := mapERPStatus(erp.StatusFlg)
    if err != nil {
        return DomainOrder{}, fmt.Errorf("未知的 ERP 状态码: %d", erp.StatusFlg)
    }
    return DomainOrder{
        OrderID:    NewOrderID(erp.OrdNo),
        CustomerID: NewCustomerID(erp.CustCode),
        Total:      NewMoney(erp.TotalAmt, CNY),
        Status:     status,
    }, nil
}

详细实现请参见 防腐层与开放主机服务

3.6 开放主机服务(Open Host Service)

上游定义一组公开协议(API),供多个下游使用。

  • 适用场景:上游需要服务多个不同的下游上下文;
  • 组织前提:上游有专门的接口设计和版本管理能力;
  • 典型形式:RESTful API、gRPC 服务、GraphQL 端点。
              ┌───────────────┐
              │ Open Host     │
              │ Service       │
              │ (标准化 API)   │
              └───────┬───────┘
                      │
          ┌───────────┼───────────┐
          │           │           │
    ┌─────┴─────┐┌────┴────┐┌────┴────┐
    │ 下游 A    ││ 下游 B  ││ 下游 C  │
    └───────────┘└─────────┘└─────────┘

3.7 发布语言(Published Language)

上下文之间通过一种公共的、文档化的数据交换格式进行通信。

  • 适用场景:需要在多个上下文之间交换领域数据,且格式需要标准化;
  • 常见形式:JSON Schema、Protocol Buffers、Avro Schema、XML Schema;
  • 关系:通常与 Open Host Service 配合使用。
// published_language/order_events.proto
syntax = "proto3";
package order.events;

message OrderCreatedEvent {
    string order_id = 1;
    string customer_id = 2;
    repeated LineItem items = 3;
    MoneyValue total = 4;
    google.protobuf.Timestamp created_at = 5;
}

message LineItem {
    string product_id = 1;
    int32 quantity = 2;
    MoneyValue unit_price = 3;
}

message MoneyValue {
    string amount = 1; // 使用字符串避免浮点精度问题
    string currency = 2;
}

3.8 合作关系(Partnership)

两个上下文的团队建立一种对等的合作关系,共同规划和协调开发。

  • 适用场景:两个上下文高度相关,必须同步演进;
  • 组织前提:团队之间有对等的话语权,愿意共同承担协调成本;
  • 风险:协调成本随团队规模增长迅速上升。

3.9 各行其道(Separate Ways)

两个上下文之间没有任何集成关系,各自独立发展。

  • 适用场景:集成成本高于收益,或业务上确实不需要交互;
  • 注意:这是一个主动的设计决策,不是忽视集成需求。

3.10 大泥球(Big Ball of Mud)

这不是一种推荐的模式,而是对现实的描述——系统中没有清晰的上下文边界,各种概念混杂在一起。

  • 识别信号:修改任何一个功能都可能影响看似无关的部分;
  • 应对策略:在大泥球的外围建立防腐层,逐步剥离新的上下文。

四、上下文映射模式的决策树

面对两个需要集成的上下文,如何选择合适的映射模式?以下决策树提供了一个系统化的判断路径:

flowchart TD
    START["两个上下文需要集成"] --> Q1{"两个团队能否<br/>紧密协作?"}
    Q1 -->|是| Q2{"需要共享<br/>部分模型?"}
    Q1 -->|否| Q3{"下游能否影响<br/>上游的接口?"}

    Q2 -->|是| SK["共享内核<br/>Shared Kernel"]
    Q2 -->|否| PT["合作关系<br/>Partnership"]

    Q3 -->|是| CS["客户-供应商<br/>Customer-Supplier"]
    Q3 -->|否| Q4{"上游模型是否<br/>可以接受?"}

    Q4 -->|是| CF["遵从者<br/>Conformist"]
    Q4 -->|否| Q5{"集成是否<br/>值得投入?"}

    Q5 -->|是| ACL["防腐层<br/>ACL"]
    Q5 -->|否| SW["各行其道<br/>Separate Ways"]

    CS --> Q6{"上游需要服务<br/>多个下游?"}
    Q6 -->|是| OHS["开放主机服务<br/>+ 发布语言"]
    Q6 -->|否| CS2["保持客户-供应商"]

4.1 Shared Kernel vs ACL 的关键决策因素

这两种模式是最容易混淆的,以下对比帮助做出判断:

维度 Shared Kernel Anti-Corruption Layer
团队信任度 高,愿意共同维护 低或不可控
模型一致性 共享部分的模型完全一致 两侧模型可以完全独立
变更协调成本 每次修改需双方同意 各自独立修改
耦合度 高(共享代码/schema) 低(通过翻译层隔离)
适用团队规模 小团队(2-3 个上下文) 任意规模
实现成本 低(直接复用) 高(需要建设翻译层)
维护成本 高(协调成本) 中(翻译层维护)
典型场景 同一产品线的核心概念 对接遗留系统或外部服务

4.2 选择建议的总结表

模式 适用的组织关系 适用的技术场景 主要风险
Shared Kernel 紧密协作的小团队 核心概念确实相同 耦合扩散
Partnership 对等协作的团队 需要同步演进的上下文 协调成本高
Customer-Supplier 上下游关系明确 下游有合理需求 上游优先级冲突
Conformist 下游无谈判余地 上游模型基本可接受 模型污染
ACL 下游需要保护模型 对接遗留/外部系统 翻译层维护成本
OHS + PL 一对多服务 提供标准化接口 版本管理复杂度
Separate Ways 无协作关系 集成价值低于成本 数据不一致
Big Ball of Mud 遗留系统 无边界的混沌系统 所有风险

五、上下文边界与团队边界的对齐

5.1 康威定律的启示

梅尔文·康威(Melvin Conway)在 1968 年提出的康威定律(Conway’s Law)指出:

设计系统的组织,其产出的系统架构必然是该组织沟通结构的映射。

这意味着限界上下文的边界最终会趋向于团队的边界。反过来,如果你的架构边界与团队边界不一致,两者之间必然产生摩擦。

5.2 反向康威策略

反向康威策略(Inverse Conway Maneuver)是指主动调整组织结构来匹配目标架构。如果你希望系统由三个限界上下文组成,那就组建三个团队,每个团队负责一个上下文。

目标架构:
┌──────────┐  ┌──────────┐  ┌──────────┐
│ 交易上下文 │  │ 物流上下文 │  │ 支付上下文 │
└──────────┘  └──────────┘  └──────────┘

组织结构(对齐后):
┌──────────┐  ┌──────────┐  ┌──────────┐
│ 交易团队  │  │ 物流团队  │  │ 支付团队  │
│ 5-8 人   │  │ 5-8 人   │  │ 3-5 人   │
└──────────┘  └──────────┘  └──────────┘

5.3 Team Topologies 的四种团队类型

Matthew Skelton 和 Manuel Pais 在《Team Topologies》一书中定义了四种基础团队类型,与限界上下文的分类可以形成映射:

团队类型 说明 对应的子域类型
流对齐团队(Stream-aligned) 面向业务价值流交付 核心子域
使能团队(Enabling) 帮助其他团队克服技术障碍 跨多个子域
复杂子系统团队(Complicated-subsystem) 负责需要深度专业知识的组件 技术复杂的支撑子域
平台团队(Platform) 提供底层基础设施能力 通用子域

5.4 一个团队应该负责多少个上下文?

核心原则是认知负载(Cognitive Load)——一个团队能有效理解和维护的领域复杂度是有限的。

经验法则: - 一个 5-8 人的团队通常负责 1-2 个限界上下文; - 如果一个团队负责 3 个以上的上下文,说明上下文粒度可能太细,或团队需要拆分; - 如果一个上下文需要 15 人以上的团队,说明上下文粒度可能太粗。


六、工程案例:电商系统的上下文映射

6.1 背景

某电商平台在快速发展阶段,系统从单体演进为微服务。初期的服务划分按功能模块拆分(用户服务、商品服务、订单服务……),但随着业务复杂度增长,出现了以下问题:

  1. “订单服务”承担了交易、支付、物流等多个领域的逻辑;
  2. 修改价格计算规则需要同时改动促销服务和订单服务;
  3. 用户服务同时包含了认证、会员、画像三种不同的业务关注点。

6.2 重新建模

团队采用事件风暴(参见 领域事件与事件风暴)重新梳理业务领域,识别出以下限界上下文:

graph LR
    subgraph "核心子域"
        TC["交易上下文<br/>Trading Context"]
        PC["定价上下文<br/>Pricing Context"]
    end

    subgraph "支撑子域"
        SC["物流上下文<br/>Shipping Context"]
        PAY["支付上下文<br/>Payment Context"]
        INV["库存上下文<br/>Inventory Context"]
    end

    subgraph "通用子域"
        AUTH["认证上下文<br/>Auth Context"]
        NOTIFY["通知上下文<br/>Notification Context"]
    end

    TC -->|"Customer-Supplier"| SC
    TC -->|"Partnership"| PC
    TC -->|"Customer-Supplier"| PAY
    TC -->|"Customer-Supplier"| INV
    TC -->|"OHS + PL"| NOTIFY
    AUTH -->|"OHS + PL"| TC
    AUTH -->|"OHS + PL"| SC

6.3 上下文映射决策

上游 下游 映射模式 决策理由
交易 物流 Customer-Supplier 物流需求明确,交易团队愿意配合
交易 定价 Partnership 两者紧耦合,需要同步演进
交易 支付 Customer-Supplier 支付需求标准化程度高
认证 全部 OHS + PL 认证提供标准化 JWT 接口
交易 通知 OHS + PL 通知是通用能力
交易 遗留 ERP ACL ERP 模型老旧,不允许修改

6.4 效果

重新划分后,团队对齐到各自的限界上下文:

  • 交易团队和定价团队由于 Partnership 关系,采用同一个 Sprint 节奏;
  • 物流团队作为 Customer 可以向交易团队提出接口需求;
  • 认证团队维护 OHS,提供标准化的 JWT 发放和验证 API;
  • 对接遗留 ERP 系统时,交易团队通过 ACL 保护了自己的领域模型。

交付效率在三个月内提升约 40%,跨团队沟通冲突减少约 60%。


七、上下文映射的可视化工具

7.1 上下文地图

上下文地图(Context Map)是战略设计最重要的交付物之一。它用可视化的方式展示系统中所有限界上下文及其关系。

一个完整的上下文地图应该包含:

  1. 所有已识别的限界上下文;
  2. 上下文之间的映射关系(用标准化的缩写标注);
  3. 上下文的负责团队;
  4. 上下文的核心聚合。

7.2 标准缩写

缩写 模式
SK Shared Kernel
CS / U-D Customer-Supplier / Upstream-Downstream
CF Conformist
ACL Anti-Corruption Layer
OHS Open Host Service
PL Published Language
PT Partnership
SW Separate Ways
BBM Big Ball of Mud

7.3 工具推荐

工具 特点 适用阶段
白板 + 便利贴 最灵活,适合初期探索 事件风暴工作坊
Miro / FigJam 远程协作友好 远程事件风暴
Context Mapper DSL 代码化的上下文地图 设计文档化
PlantUML / Mermaid 文本化绘图 技术文档
Structurizr C4 模型集成 架构决策记录

八、战略设计的常见误区

8.1 误区一:限界上下文等于微服务

限界上下文是逻辑边界,微服务是物理边界。一个限界上下文可以是一个单体中的模块,一个微服务中的包,甚至可以跨越多个部署单元。先划上下文,再决定部署策略。

8.2 误区二:先定技术架构再识别上下文

正确的顺序是:理解业务 → 识别子域 → 划分限界上下文 → 选择映射模式 → 决定部署架构。技术架构应该服务于业务架构,而不是相反。

8.3 误区三:上下文边界一旦确定就不变

限界上下文是演进式的。随着业务发展和团队对领域理解的深入,上下文边界应该持续调整。常见的演进模式包括:

  • 拆分:一个上下文变得过大,拆分为两个;
  • 合并:两个上下文的边界模糊,合并为一个;
  • 重新定义:发现更合理的边界。

8.4 误区四:追求”完美”的上下文划分

不存在唯一正确的划分方案。两个不同的团队面对同一个业务,可能画出不同但都合理的上下文边界。关键不在于”正确”,而在于一致性和可演进性

8.5 误区五:忽视组织因素

纯技术视角的上下文划分注定失败。一个上下文如果跨越三个不同部门的职责范围,那它在组织现实中很难作为一个整体运作。


九、实施战略设计的步骤

9.1 第一步:识别核心子域

与领域专家一起,明确哪些是企业的核心竞争力。这些子域值得最深入的建模和最好的团队资源。

9.2 第二步:绘制现状上下文地图

描述系统当前的上下文关系,包括那些不理想的 Big Ball of Mud。诚实面对现状是改进的前提。

9.3 第三步:设计目标上下文地图

基于业务发展方向和组织规划,设计目标状态的上下文地图。

9.4 第四步:制定演进路径

从现状到目标不是一步到位的。需要制定分阶段的演进计划,每个阶段都应该能独立交付业务价值。

阶段 1:在大泥球外围建立 ACL,隔离核心域
阶段 2:从大泥球中剥离第一个限界上下文
阶段 3:建立 OHS,为新上下文提供标准接口
阶段 4:逐步迁移剩余功能到独立上下文

9.5 第五步:持续验证和调整

每个 Sprint 或迭代周期结束后,回顾上下文边界是否仍然合理,映射模式是否需要调整。


十、战略设计的综合权衡

决策维度 细粒度上下文 粗粒度上下文
团队自治 高:每个团队独立决策 低:需要内部协调
模型纯净度 高:每个上下文语义清晰 低:可能混合多种语义
集成复杂度 高:上下文间交互多 低:内部调用
数据一致性 难:需要跨上下文最终一致 易:事务边界内强一致
部署独立性 高:各自独立部署 低:需要协调部署
认知负载 低:每个上下文容易理解 高:需要理解多个概念
运维成本 高:更多的服务和基础设施 低:更少的运维对象
性能 可能受跨服务调用影响 内部调用效率高
适合阶段 成熟业务、大团队 创业期、小团队

十一、从战略到战术

战略设计回答的是”系统应该分成哪几块”的问题,而战术设计回答的是”每一块内部应该怎么组织”的问题。战略设计的输出——限界上下文和上下文映射——是战术设计的输入。

在下一篇文章中,我们将深入限界上下文的内部,探讨聚合(Aggregate)、实体(Entity)、值对象(Value Object)等战术模式的设计原则和实践方法。

下一篇:DDD 战术模式:聚合、实体与值对象


参考资料

  1. Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley, 2003.
  2. Vernon, Vaughn. Implementing Domain-Driven Design. Addison-Wesley, 2013.
  3. Brandolini, Alberto. Introducing EventStorming. Leanpub, 2021.
  4. Skelton, Matthew; Pais, Manuel. Team Topologies. IT Revolution, 2019.
  5. Context Mapper DSL 官方文档:https://contextmapper.org/
  6. Conway, Melvin. “How Do Committees Invent?” Datamation, 1968.
  7. Fowler, Martin. “Bounded Context.” martinfowler.com.
  8. 张逸.《解构领域驱动设计》. 人民邮电出版社, 2021.

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-13 · architecture

【系统架构设计】复杂性管理:架构的核心战场

系统复杂性是架构腐化的根源——本文从 Brooks 的本质复杂性与偶然复杂性划分出发,结合认知负荷理论与 Parnas 的信息隐藏原则,系统阐述复杂性的来源、度量与控制手段,并给出可操作的架构策略

2026-04-13 · architecture

【系统架构设计】DDD 战术模式:聚合、实体与值对象

某团队在实施领域驱动设计时,把整个"订单"建模为一个聚合根(Aggregate Root),其中包含订单基本信息、所有订单行、配送信息、支付记录、物流轨迹、评价数据。结果这个聚合加载一次需要从 7 张表联查,保存一次需要锁定整个订单树。并发下单高峰期,数据库锁等待飙升至秒级。这就是典型的"大聚合"反模式——聚合的边界画…

2026-04-13 · architecture

【系统架构设计】防腐层与开放主机服务:系统集成的 DDD 方案

某金融科技公司正在构建新一代交易系统。新系统使用领域驱动设计,模型清晰、代码整洁。然而它必须对接一套运行了 15 年的核心银行系统(Core Banking System)——这套系统的接口返回 COBOL 风格的定长字段,状态码用两位数字表示("01"正常、"02"冻结、"99"未知),金额用"分"而非"元"为单位。…

2026-04-13 · architecture

【系统架构设计】DDD 与微服务:用领域模型划分服务边界

某电商团队按数据库表拆分微服务——用户服务管 tuser,商品服务管 tproduct,订单服务管 torder。看起来边界清晰,实际运行中却发现:下单需要同步调用商品服务查价格、调用库存服务检查库存、调用优惠服务算折扣、调用用户服务查地址,一个下单请求扇出 4 次 RPC,任意一个服务超时整条链路就失败。这种"一实体…