AgentSkillsCN

domain-driven-design

面向软件开发的领域驱动设计体系。当您需要以 DDD 原则设计新系统,或朝着 DDD 方向重构现有代码库,生成代码脚手架(实体、聚合、仓库、领域事件),促进事件风暴会议,创建限界上下文地图,或以 DDD 的视角开展代码审查时,请使用此技能。它既涵盖战略设计(限界上下文、子域、上下文地图、通用语言),也涵盖战术设计(实体、值对象、聚合、领域服务、仓库)。无论采用何种主流架构模式(六边形/端口与适配器、CQRS、事件溯源、清洁架构),它都提供与语言无关的指导,并以 Python 和 TypeScript 为例,给出具体的应用示例。

SKILL.md
--- frontmatter
name: domain-driven-design
description: Domain-Driven Design system for software development. Use when designing new systems with DDD principles, refactoring existing codebases toward DDD, generating code scaffolding (entities, aggregates, repositories, domain events), facilitating Event Storming sessions, creating bounded context maps, or performing code reviews with a DDD lens. Covers both strategic design (bounded contexts, subdomains, context maps, ubiquitous language) and tactical design (entities, value objects, aggregates, domain services, repositories). Supports all major architecture patterns (Hexagonal/Ports & Adapters, CQRS, Event Sourcing, Clean Architecture) with language-agnostic guidance and concrete examples in Python and TypeScript.

Domain-Driven Design Skill

Apply DDD to build software that reflects deep understanding of the business domain.

Quick Reference

TaskReference
Bounded contexts, subdomains, context mapsstrategic-design.md
Entities, value objects, aggregates, repositoriestactical-design.md
Hexagonal, CQRS, Event Sourcing, Clean Architecturearchitecture-patterns.md
Event Storming facilitation & documentationevent-storming.md
Python implementations (Pydantic, SQLAlchemy, FastAPI)python-patterns.md
TypeScript implementations (NestJS, TypeORM, Prisma)typescript-patterns.md
DDD code review criteriacode-review.md

Core Workflow

1. Identify the Task Type

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

2. Strategic Before Tactical

Always establish strategic design first:

  1. Identify subdomains (Core, Supporting, Generic)
  2. Define bounded contexts and their boundaries
  3. Map context relationships (upstream/downstream, conformist, ACL, etc.)
  4. Establish ubiquitous language per context

3. Select Architecture Pattern

Choose based on domain complexity and requirements:

PatternWhen to Use
LayeredSimple CRUD, low complexity
HexagonalNeed to isolate domain from infrastructure
Clean ArchitectureComplex business rules, multiple delivery mechanisms
CQRSDifferent read/write models, complex queries
Event SourcingAudit trail required, temporal queries, event-driven

Patterns can be combined (e.g., Hexagonal + CQRS + Event Sourcing).

4. Apply Tactical Patterns

Select tactical building blocks based on needs:

Building BlockPurpose
EntityIdentity matters, mutable, lifecycle
Value ObjectDefined by attributes, immutable, no identity
AggregateConsistency boundary, transactional unit
Domain ServiceStateless operations spanning multiple aggregates
RepositoryCollection-like interface for aggregate persistence
Domain EventRecord of something significant that happened
FactoryComplex object creation logic
SpecificationEncapsulated business rules for querying/validation

5. Implementation Guidelines

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:

Project Structure Template

code
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 consumers

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

When NOT to Use 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