DDD在公司的实践记录
本文档旨在提供一套一心堂研发内部标准的领域驱动设计(DDD)分层架构规范。其核心目标是:
- 统一架构认知:在所有团队中建立一致的架构语言和设计准则。
- 明确职责边界:通过更精细化的分层,清晰定义各模块的职责,防止业务逻辑泄露和代码腐化。
- 提升协作效率:通过标准化的sdk契约模块,实现安全、高效的跨域(Bounded Context)交互。
- 保障系统演进:使每个业务域能够独立、安全地进行开发、部署和扩展。
2. 核心原则
Section titled “2. 核心原则”- 业务域独立 (Bounded Context First):每个业务域都是一个独立的Maven项目,拥有自己的代码仓库(Git Repo),代码仓库本身即定义了团队所有权。
- 精细化分层 (Fine-grained Layering):严格遵循表现层、应用层、领域层、基础设施层的四层架构思想。
- 依赖倒置 (Dependency Inversion Principle):高层模块不依赖于低层模块的具体实现。领域层是整个架构的核心,不依赖于任何其他层。
- 面向接口编程 (Programming to an Interface):所有跨层或需要灵活替换的服务,都应通过接口进行通信。
3. 通用项目结构规范
Section titled “3. 通用项目结构规范”为了实现规范的通用性,我们使用占位符 {business-domain}。在实际创建项目时,请替换为具体的业务名称(例如:order, product, user)。
3.1 标准化多模块结构树
Section titled “3.1 标准化多模块结构树”一个独立的业务域项目 project-root 的标准结构如下:
{business-domain}-{具体业务} (业务域根项目 - Git Repository Root)├── pom.xml (Parent POM, 管理所有子模块和依赖)│├── {business-domain}-bootstrap/ (1. 启动与装配模块)│ ├── pom.xml│ └── src/main/java/com/moatkon/{business-domain}/bootstrap/│ └── Bootstrap.java (Spring Boot启动类)│├── {business-domain}-interface/ (2. 表现层/适配器模块)│ ├── pom.xml│ └── src/main/java/com/moatkon/{business-domain}/interfaces/│ ├── controller/ (RESTful Controllers)│ └── mq/ (MQ Listeners)│├── {business-domain}-application/ (3. 应用层模块)│ ├── pom.xml│ └── src/main/java/com/moatkon/{business-domain}/application/│ └── impl/ (应用服务实现)│├── {business-domain}-sdk/ (4. 对外接口/契约模块)│ ├── pom.xml│ └── src/main/java/com/moatkon/{business-domain}/sdk/│ ├── api/ (供其他域调用的Feign/Dubbo接口)│ ├── dto/ (数据传输对象 DTO)│ └── event/ (领域事件定义)│├── {business-domain}-domain/ (5. 领域层模块)│ ├── pom.xml│ └── src/main/java/com/moatkon/{business-domain}/domain/│ ├── aggregate/ (聚合)│ ├── service/ (领域服务)│ └── repository/ (仓储接口)│└── {business-domain}-infrastructure/ (6. 基础设施层模块) ├── pom.xml └── src/main/java/com/moatkon/{business-domain}/infrastructure/ ├── repository/ (持久化实现, 如JPA/MyBatis) └── external/ (三方服务实现)
3.2 模块职责详解
Section titled “3.2 模块职责详解”模块名 | 核心职责 | 依赖关系 |
{business-domain}-bootstrap | 应用启动入口 (Composition Root)。负责应用的启动、配置的组装和Bean的装配。这是应用的“main”函数所在。 | 依赖所有其他模块(interface, application, infrastructure) |
{business-domain}-interface | 表现层 (Presentation Layer)。处理外部输入,如RESTful API请求、MQ消息订阅等。它将外部请求适配到应用层。 | 依赖 application |
{business-domain}-application | 应用层 (Application Layer)。编排领域服务完成业务用例,管理事务、安全等横切关注点。不包含业务规则。 | 依赖 domain 和 sdk (用于调用其他域) |
{business-domain}-sdk | 跨域通信契约 (Anti-Corruption Layer)。定义对外暴露的能力,供其他业务域调用。这是团队间协作的边界。 | 不依赖任何其他内部模块 |
{business-domain}-domain | 核心领域层 (Domain Layer)。包含所有业务逻辑、规则和状态。与技术框架完全解耦。 | 不依赖任何其他层 |
{business-domain}-infrastructure | 基础设施层 (Infrastructure Layer)。提供技术实现,如数据库访问、消息发送等。 | 依赖 domain (实现其接口) 和 sdk (契约) |
4. 分层架构定义与依赖关系
Section titled “4. 分层架构定义与依赖关系”4.1 依赖规则
Section titled “4.1 依赖规则”- 单向依赖:依赖关系严格单向。例如 interface 模块依赖 application 模块。
- 依赖倒置:domain 层定义接口,infrastructure 层实现接口。应用层和表现层仅依赖于 domain 层的抽象。
- 启动模块 (bootstrap):作为应用的“粘合剂”,它依赖所有实现模块,以完成整个应用的组装和启动。
- 跨域依赖 (sdk):任何外部业务域 必须且只能 依赖本域的 sdk 模块来进行通信。
5. 命名与协作规范
Section titled “5. 命名与协作规范”5.1 包名 (Package Name)
Section titled “5.1 包名 (Package Name)”com.moatkon.{business-domain}.{module-name-short}
示例:
- Controller: com.moatkon.archetype.interfaces
- 应用服务: com.moatkon.archetype.application
- 聚合根: com.moatkon.archetype.domain
- 对外API: com.moatkon.archetype.sdk
5.3 团队协作与集成
Section titled “5.3 团队协作与集成”- 契约(SDK)先行: 在进行跨域功能开发前,提供方团队应先在 sdk 模块中定义好接口和DTO,并发布一个版本。
- 通信方式:
- 同步调用: 通过 sdk 模块定义的 Feign。
- 异步事件: 在 sdk 模块中定义事件DTO,通过 infrastructure 层的MQ生产者发送。消费方在 interface 模块中创建MQ监听器。
6. 共享内核 (Shared Kernel)
Section titled “6. 共享内核 (Shared Kernel)”- 对于多域共享的核心模型(如UserId, Money),应建立独立的shared-kernel项目。
- shared-kernel 需严格评审。
例如: 订单侧的共享内核是order-framework项目,专注于订单内部共享。order-framework项目内部包含order-common、order-types等子module