Claude-skill-registry arch-ddd
Apply Domain-Driven Design (DDD) architecture to backend projects. Use for tasks like defining bounded contexts, aggregates and invariants, entities/value objects, domain services, repositories, domain events, application services, anti-corruption layers, and aligning code structure and APIs with domain language while avoiding anemic models.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/arch-DDD" ~/.claude/skills/majiayu000-claude-skill-registry-arch-ddd && rm -rf "$T"
manifest:
skills/data/arch-DDD/SKILL.mdtags
source content
arch-ddd
Use this skill to design or refactor a backend system toward DDD (领域驱动设计) with clear boundaries and maintainable evolution.
Core principles (practical)
- Ubiquitous Language: domain terms in code, APIs, and docs must match.
- Bounded Contexts: separate subdomains with explicit boundaries; integrate via contracts.
- Aggregate: the unit of consistency; enforce invariants inside the aggregate.
- Application vs Domain: application services orchestrate; domain model owns rules.
- Ports & Adapters: infrastructure depends on domain/application, not the other way around.
Deliverables (what “good” looks like)
- A list of bounded contexts + their responsibilities and integration points.
- Aggregate definitions (root, entities, value objects) + invariants.
- Command/query use-cases mapped to application services.
- Repository interfaces (in domain/application) + infra implementations.
- Domain events for cross-context integration (outbox if needed).
Workflow
- Understand the domain
- Identify actors, key workflows, nouns/verbs, and business constraints.
- Extract invariants (must always be true) and policies (may change).
- Split bounded contexts
- Group capabilities that change together.
- Define context boundaries and “ownership” of data/behaviors.
- For each boundary: define integration style (sync API, async events, file/batch).
- Define aggregates
- Start from invariants and transactions, not tables.
- Choose one aggregate root per consistency boundary.
- Keep aggregates small; reference other aggregates by ID only.
- Define application services (use cases)
- Each endpoint maps to a use-case (command/query).
- Commands: validate, load aggregate, execute domain behavior, persist, publish events.
- Queries: read-optimized models (can be denormalized) and avoid domain coupling.
- Persistence strategy
- Repository interface returns aggregates; hide ORM/SQL details.
- Avoid cross-aggregate joins in write paths; consider read models for queries.
- Use domain IDs (string/ULID/UUID) consistently across layers.
- Integration patterns
- Cross-context sync: explicit contract DTOs; add Anti-Corruption Layer (ACL) when mapping is non-trivial.
- Cross-context async: domain events; versioned payloads; idempotent consumers.
- Testing approach
- Domain: fast unit tests around invariants and behaviors.
- Application: use-case tests with fakes for repositories/outbox.
- Integration: contract tests for APIs/events; DB tests only where needed.
Anti-patterns to avoid
- “Everything is a service”: domain logic scattered in application/service layer.
- Anemic domain model: entities are just getters/setters.
- Aggregate too large: one aggregate per table or “user” becomes god object.
- Tight coupling to DB schema: domain types leak ORM annotations everywhere.
Code organization (suggested)
: aggregates, entities, value objects, domain services, domain events, repository interfacesdomain/
: use-cases, command/query handlers, DTOs, mappers, transaction boundaryapplication/
: DB/ORM, message bus, external clients, repository implementationsinfrastructure/
(orinterfaces/
): controllers/routers, request/response models, authapi/