在软件开发中,我们经常面临业务逻辑复杂、代码耦合度高、难以维护的困境。领域驱动设计 (Domain-Driven Design, DDD) 提供了一套完整的思想体系,帮助我们通过将软件实现与核心业务概念紧密绑定,来解决复杂业务系统的设计问题。

本文将从战术设计(分层架构)和战略设计(限界上下文与映射)两个维度,为你梳理 DDD 的核心概念。

一、 战术设计:分层架构 (Layered Architecture)

DDD 的分层架构旨在通过 **关注点分离 (Separation of Concerns)**,确保业务逻辑的纯粹性,不被技术实现细节污染。

1. 典型的四层架构

在 DDD 中,标准的架构通常分为四层,从上到下依次为:

(1) 用户接口层 (User Interface / Presentation Layer)

  • 职责:系统与外界(人或外部系统)交互的窗口。负责向用户展示信息和解释用户指令。
  • 包含:Controller、DTO、API 接口定义。
  • 核心原则不包含任何业务逻辑。只负责数据格式转换(如 JSON 转对象)和简单校验。

(2) 应用层 (Application Layer)

  • 职责:业务逻辑的 **协调者 (Orchestrator)**。它定义软件要完成的任务,并指挥领域对象来解决问题。
  • 包含:Application Service(应用服务)。
  • 核心原则:这一层 很薄。它不处理业务规则,只负责编排任务(如:开启事务 -> 调用聚合根 -> 保存 -> 发送事件)。

(3) 领域层 (Domain Layer) —— 核心

  • 职责:业务软件的核心所在。负责表达业务概念,处理业务状态信息和业务规则。
  • 包含
    • **实体 (Entities)**:有唯一标识的对象(如订单)。
    • **值对象 (Value Objects)**:无唯一标识,通过属性描述特征的对象(如地址)。
    • **聚合 (Aggregates)**:保证数据一致性的边界。
    • **仓储接口 (Repository Interfaces)**:定义数据存取的契约。
  • 核心原则绝对纯净。不依赖任何具体的技术框架(如 Spring)或基础设施。

(4) 基础设施层 (Infrastructure Layer)

  • 职责:为各层提供通用的技术能力,“落地”技术细节。
  • 包含:数据库实现 (MySQL/MongoDB)、消息队列、第三方 API 调用、缓存 (Redis) 等。

2. 核心思想:依赖倒置 (DIP)

在传统架构中,依赖通常是自顶向下的(UI -> Service -> DAO/DB)。但在 DDD 中,这是一个反模式。为了保持领域层的纯洁性,我们需要采用 依赖倒置原则

  • 定义:领域层定义接口(如 OrderRepository)。
  • 实现:基础设施层实现该接口(如 OrderRepositoryImpl)。
  • 注入:运行时通过 IoC 容器注入。

最终的依赖关系变为:

Infrastructure -> Domain <- Application <- UI

Domain 层变成了架构的圆心(洋葱架构),它不依赖任何外部层。


3. 为什么要这么设计?

  1. 隔离复杂度:业务与技术解耦。技术栈升级(如换数据库)不影响核心业务代码。
  2. 高可测试性:核心业务逻辑不需要启动数据库即可进行单元测试,速度快且稳定。
  3. 通用语言落地:代码结构直接反映业务模型,类名即业务术语,减少沟通成本。

二、 战略设计:限界上下文 (Bounded Context)

如果说分层架构解决了“怎么写代码”的问题,那么 限界上下文 就是解决“庞大的系统如何拆分”的问题。

1. 什么是限界上下文?

限界上下文是一个显式的边界。在这个边界内,领域模型和 通用语言 (Ubiquitous Language) 有特定的含义和适用范围。

核心逻辑:同一个名词,在不同的上下文里,代表完全不同的事物。

2. 经典案例:什么是“商品”?

在一个电商系统中,如果不划分上下文,你会得到一个臃肿的 Product 类。但在 DDD 中,我们承认差异:

  • 销售上下文:关注价格、描述、图片。这里的“商品”是为了
  • 库存上下文:关注重量、体积、货架位。这里的“商品”是为了

通过划分上下文,我们不再强求统一的大模型,而是建立了两个独立的模型,它们之间通过 ID 关联。这正是 微服务拆分的最佳理论依据


三、 两个世界的桥梁:上下文映射 (Context Mapping)

划分了边界(限界上下文)后,不同的“孤岛”之间如何交互?这就是 上下文映射 要解决的问题。我们可以根据“话语权”和“依赖程度”分为三类:

1. 遵奉者 (Conformist) —— 下游被迫妥协

  • 场景:上游系统强势且无法修改。
  • 做法:下游直接复用上游的模型。
  • 代价:模型被污染,耦合度极高。

2. 防腐层 (Anticorruption Layer, ACL) —— ⭐ 推荐

  • 场景:不想让外部系统的“烂模型”污染自己的核心领域。
  • 做法:在系统边界建立一层“翻译官”。外部数据进入时,先经过 ACL 转换为内部纯净的领域对象。
  • 应用:对接旧系统、对接第三方支付(微信/支付宝)等。

3. 开放主机服务 (Open Host Service, OHS) —— 上游制定标准

  • 场景:你是核心服务(如用户中心),有很多下游依赖你。
  • 做法:定义一套标准的、公开的 API 协议(发布语言),让所有下游遵守你的标准。
  • 优势:上游只需维护一套逻辑,这也是微服务间调用的主流模式。

总结

DDD 不是银弹,但它是治理复杂业务系统的利器:

  • 分层架构(战术)像整理衣柜,通过分类存放(各层职责)和防止混用(依赖倒置),让代码井井有条。
  • 限界上下文(战略)像划分部门,明确每个部门(上下文)的职责边界,避免职能重叠。
  • 上下文映射部门间协议,规定了部门之间如何沟通和协作(ACL/OHS)。

希望这篇文章能帮你建立对 DDD 的宏观认识,迈出架构设计的重要一步。

最后附上,个人博客网站:Southblock’Blog,内容更多,更新,欢迎参观。