1. 领域驱动设计概述

1.1 DDD 核心概念

领域驱动设计(Domain-Driven Design,DDD)由 Eric Evans 于 2003 年提出,是一种以领域模型为核心的软件设计方法论。DDD 强调软件系统的复杂性与业务领域的复杂性直接相关,因此架构设计必须围绕业务领域展开,而非技术实现。

DDD 的核心概念可归纳为以下三层:

层级 核心概念 说明
领域层 实体(Entity)、值对象(Value Object)、聚合(Aggregate) 表达业务逻辑与规则的核心模型
应用层 领域服务(Domain Service)、应用服务(Application Service) 协调领域对象完成用例流程
基础设施层 仓储(Repository)、工厂(Factory)、事件(Event) 提供持久化、消息、外部接口等技术支持
关键原则:领域模型是系统的“心脏”,技术实现(数据库、框架、消息队列)必须服从于领域模型的表达,而非反过来。

1.2 战略设计与战术设计

DDD 将设计过程分为两个层次:战略设计(Strategic Design)与战术设计(Tactical Design)。两者分别解决“如何划分边界”和“如何实现模型”的问题。

战略设计

  • 限界上下文(Bounded Context):每个上下文拥有独立的领域模型和语言,避免概念混淆。
  • 上下文映射(Context Map):描述不同上下文之间的协作关系(如防腐层、开放主机服务、共享内核等)。
  • 通用语言(Ubiquitous Language):团队与业务专家使用同一套术语,贯穿代码、文档、讨论。

战术设计

  • 实体:具有唯一标识、生命周期可追踪的对象。
  • 值对象:无标识、不可变、描述性对象。
  • 聚合:一组相关对象的集合,通过聚合根保证一致性。
  • 领域事件:记录业务中发生的重要事实。
  • 仓储:提供聚合的持久化与检索接口。
实践建议:在 Go 项目中,战略设计优先于战术设计。先通过事件风暴(Event Storming)或业务流程图识别限界上下文,再为每个上下文设计聚合与实体。

1.3 领域边界的重要性

领域边界是 DDD 战略设计的核心产出。没有清晰的边界,领域模型会退化为“贫血模型”或“大泥球”架构。边界的作用体现在以下方面:

  1. 语言隔离:不同上下文使用不同的通用语言,避免“用户”一词在订单上下文和客服上下文中含义冲突。
  2. 模型独立:每个上下文内的模型可以独立演进,不受外部变化影响。
  3. 团队自治:大型项目中,每个限界上下文可由独立团队负责,降低沟通成本。
  4. 技术解耦:边界内可以选择最适合的技术栈(如不同数据库、消息队列)。
常见误区:将微服务数量等同于限界上下文数量。实际上,一个限界上下文可以包含多个微服务,也可以只包含一个模块。边界是逻辑概念,微服务是部署单元。
DDD 战略与战术设计分层架构 DDD 战略与战术设计分层架构 战略设计层 限界上下文 上下文映射 通用语言 战术设计层 实体 值对象 聚合 领域事件 仓储 工厂 领域服务 应用服务 战略设计定义“在哪里划分边界”,战术设计定义“边界内如何建模”

1.4 限界上下文与领域边界的映射关系

限界上下文是领域边界的具体表现形式。在 Go 项目中,一个限界上下文通常对应一个独立的 Go Module 或 Package。以下表格展示了不同规模项目中的边界映射策略:

项目规模 限界上下文数量 Go 组织方式 典型示例
小型(1-3 人) 2-4 个 单个仓库内多 package 订单上下文、支付上下文
中型(4-10 人) 4-8 个 多 Module 单仓库 用户上下文、商品上下文、库存上下文
大型(10+ 人) 8-20 个 多仓库多 Module 每个上下文独立 Git 仓库
Go 实践提示:使用 go.work 文件管理多 Module 项目,可以在开发阶段保持本地依赖的灵活性,同时保持发布时的独立版本控制。
限界上下文与 Go Module 映射关系 限界上下文与 Go Module 映射关系 订单上下文 go module: order-service - entity/order.go - entity/line_item.go - repository/order_repo.go - service/order_service.go - handler/http_handler.go 支付上下文 go module: payment-service - entity/payment.go - entity/transaction.go - repository/payment_repo.go - service/payment_service.go - adapter/alipay.go 库存上下文 go module: inventory-service - entity/product.go - entity/stock.go - repository/inventory_repo.go - service/inventory_service.go - handler/grpc_handler.go 每个限界上下文对应一个独立的 Go Module,拥有自己的实体、仓储、服务和接口层

1.5 本章小结

  • DDD 的核心在于领域模型,而非技术实现。
  • 战略设计关注边界划分,战术设计关注模型实现。
  • 领域边界通过限界上下文表达,在 Go 中映射为独立的 Module 或 Package。
  • 清晰的边界带来语言统一、模型独立、团队自治、技术解耦四大收益。