domain-driven-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDomain-Driven Design Skill
Domain-Driven Design (DDD) 技能
Apply DDD to build software that reflects deep understanding of the business domain.
运用DDD构建能深刻反映业务领域理解的软件。
Quick Reference
快速参考
| Task | Reference |
|---|---|
| Bounded contexts, subdomains, context maps | strategic-design.md |
| Entities, value objects, aggregates, repositories | tactical-design.md |
| Hexagonal, CQRS, Event Sourcing, Clean Architecture | architecture-patterns.md |
| Event Storming facilitation & documentation | event-storming.md |
| Python implementations (Pydantic, SQLAlchemy, FastAPI) | python-patterns.md |
| TypeScript implementations (NestJS, TypeORM, Prisma) | typescript-patterns.md |
| DDD code review criteria | code-review.md |
| 任务 | 参考文档 |
|---|---|
| 限界上下文、子域、上下文映射 | strategic-design.md |
| 实体、值对象、聚合、仓库 | tactical-design.md |
| 六边形架构、CQRS、事件溯源、整洁架构 | architecture-patterns.md |
| Event Storming 引导与文档化 | event-storming.md |
| Python 实现(Pydantic、SQLAlchemy、FastAPI) | python-patterns.md |
| TypeScript 实现(NestJS、TypeORM、Prisma) | typescript-patterns.md |
| DDD 代码评审标准 | code-review.md |
Core Workflow
核心工作流
1. Identify the Task Type
1. 识别任务类型
Designing new system? → Start with strategic design, then tactical
Refactoring existing code? → Assess current state, identify bounded contexts, refactor incrementally
Generating scaffolding? → Determine patterns needed, generate code
Event Storming? → Follow facilitation guide
Code review? → Apply DDD checklist
设计新系统? → 从战略设计入手,再推进战术设计
重构现有代码? → 评估当前状态,识别限界上下文,逐步重构
生成代码脚手架? → 确定所需模式,生成代码
开展Event Storming? → 遵循引导指南
代码评审? → 应用DDD检查清单
2. Strategic Before Tactical
2. 先战略,后战术
Always establish strategic design first:
- Identify subdomains (Core, Supporting, Generic)
- Define bounded contexts and their boundaries
- Map context relationships (upstream/downstream, conformist, ACL, etc.)
- Establish ubiquitous language per context
始终先完成战略设计:
- 识别子域(核心子域、支持子域、通用子域)
- 定义限界上下文及其边界
- 映射上下文关系(上游/下游、遵循者、防腐层等)
- 为每个上下文建立通用语言
3. Select Architecture Pattern
3. 选择架构模式
Choose based on domain complexity and requirements:
| Pattern | When to Use |
|---|---|
| Layered | Simple CRUD, low complexity |
| Hexagonal | Need to isolate domain from infrastructure |
| Clean Architecture | Complex business rules, multiple delivery mechanisms |
| CQRS | Different read/write models, complex queries |
| Event Sourcing | Audit trail required, temporal queries, event-driven |
Patterns can be combined (e.g., Hexagonal + CQRS + Event Sourcing).
根据领域复杂度和需求选择:
| 模式 | 适用场景 |
|---|---|
| 分层架构 | 简单CRUD、低复杂度场景 |
| 六边形架构 | 需要将领域与基础设施隔离的场景 |
| 整洁架构 | 业务规则复杂、存在多种交付机制的场景 |
| CQRS | 读写模型不同、查询逻辑复杂的场景 |
| 事件溯源 | 需要审计追踪、时序查询、事件驱动的场景 |
模式可以组合使用(例如:六边形架构 + CQRS + 事件溯源)。
4. Apply Tactical Patterns
4. 应用战术模式
Select tactical building blocks based on needs:
| Building Block | Purpose |
|---|---|
| Entity | Identity matters, mutable, lifecycle |
| Value Object | Defined by attributes, immutable, no identity |
| Aggregate | Consistency boundary, transactional unit |
| Domain Service | Stateless operations spanning multiple aggregates |
| Repository | Collection-like interface for aggregate persistence |
| Domain Event | Record of something significant that happened |
| Factory | Complex object creation logic |
| Specification | Encapsulated business rules for querying/validation |
根据需求选择战术构建块:
| 构建块 | 用途 |
|---|---|
| 实体 | 具有唯一标识、可变、有生命周期的对象 |
| 值对象 | 由属性定义、不可变、无唯一标识的对象 |
| 聚合 | 一致性边界、事务单元 |
| 领域服务 | 跨多个聚合的无状态操作 |
| 仓库 | 用于聚合持久化的类集合接口 |
| 领域事件 | 记录领域中发生的重要事件 |
| 工厂 | 复杂对象的创建逻辑封装 |
| 规格 | 用于查询/验证的业务规则封装 |
5. Implementation Guidelines
5. 实现指南
General principles:
- Domain layer has ZERO infrastructure dependencies
- Depend on abstractions (interfaces/protocols), not concretions
- One aggregate = one repository = one transaction
- Aggregates reference other aggregates by ID only
- Validate invariants within aggregate boundaries
- Use domain events for cross-aggregate communication
Language selection:
- Read python-patterns.md for Python with Pydantic, SQLAlchemy, FastAPI
- Read typescript-patterns.md for TypeScript with NestJS, TypeORM, Prisma
通用原则:
- 领域层完全独立于基础设施依赖
- 依赖抽象(接口/协议),而非具体实现
- 一个聚合对应一个仓库,对应一个事务
- 聚合仅通过ID引用其他聚合
- 在聚合边界内验证不变量
- 使用领域事件实现跨聚合通信
语言选型参考:
- 若使用Python,可阅读 python-patterns.md(基于Pydantic、SQLAlchemy、FastAPI)
- 若使用TypeScript,可阅读 typescript-patterns.md(基于NestJS、TypeORM、Prisma)
Project Structure Template
项目结构模板
src/
├── domain/ # Pure domain logic (no dependencies)
│ ├── model/ # Entities, Value Objects, Aggregates
│ ├── service/ # Domain Services
│ ├── event/ # Domain Events
│ ├── repository/ # Repository interfaces (ports)
│ └── specification/ # Business rule specifications
├── application/ # Use cases, orchestration
│ ├── command/ # Command handlers (write)
│ ├── query/ # Query handlers (read)
│ ├── dto/ # Data transfer objects
│ └── service/ # Application services
├── infrastructure/ # External concerns
│ ├── persistence/ # Repository implementations
│ ├── messaging/ # Event bus, message queue
│ └── external/ # Third-party integrations
└── interface/ # Delivery mechanisms
├── api/ # REST/GraphQL controllers
├── cli/ # Command-line interface
└── event/ # Event consumerssrc/
├── domain/ # 纯领域逻辑(无依赖)
│ ├── model/ # 实体、值对象、聚合
│ ├── service/ # 领域服务
│ ├── event/ # 领域事件
│ ├── repository/ # 仓库接口(端口)
│ └── specification/ # 业务规则规格
├── application/ # 用例、编排逻辑
│ ├── command/ # 命令处理器(写操作)
│ ├── query/ # 查询处理器(读操作)
│ ├── dto/ # 数据传输对象
│ └── service/ # 应用服务
├── infrastructure/ # 外部相关实现
│ ├── persistence/ # 仓库实现
│ ├── messaging/ # 事件总线、消息队列
│ └── external/ # 第三方集成
└── interface/ # 交付机制
├── api/ # REST/GraphQL控制器
├── cli/ # 命令行接口
└── event/ # 事件消费者Anti-Patterns to Avoid
需避免的反模式
- Anemic Domain Model: Entities with only getters/setters, logic in services
- God Aggregate: Too many entities in one aggregate
- Shared Kernel Abuse: Overusing shared code between contexts
- Infrastructure Leak: Database concerns in domain layer
- Missing Ubiquitous Language: Technical terms instead of domain terms
- Aggregate Reference by Object: Should reference by ID only
- Transaction Across Aggregates: Violates consistency boundaries
- 贫血领域模型:实体仅包含getter/setter,业务逻辑在服务中实现
- 上帝聚合:一个聚合中包含过多实体
- 共享内核滥用:在上下文之间过度使用共享代码
- 基础设施泄漏:领域层中包含数据库相关逻辑
- 缺失通用语言:使用技术术语而非领域术语
- 聚合直接引用对象:应仅通过ID引用
- 跨聚合事务:违反一致性边界
When NOT to Use DDD
不适合使用DDD的场景
DDD adds complexity. Avoid for:
- Simple CRUD applications
- Technical/infrastructure projects without complex business logic
- Prototypes or throwaway code
- Teams unfamiliar with the domain (learn domain first)
Use DDD when:
- Complex, evolving business logic
- Long-lived systems requiring maintainability
- Multiple teams working on related domains
- Domain experts available for collaboration
DDD会增加复杂度,以下场景应避免使用:
- 简单CRUD应用
- 无复杂业务逻辑的技术/基础设施项目
- 原型或一次性代码
- 团队对领域不熟悉(先了解领域)
适合使用DDD的场景:
- 复杂且不断演化的业务逻辑
- 需要长期维护的系统
- 多个团队协作开发相关领域
- 有领域专家可参与协作