Domain-Driven Design patterns. Bounded contexts, aggregates, entities, value objects, domain events, repositories, and application services. Strategic and tactical DDD for complex business domains. USE WHEN: user mentions "DDD", "Domain-Driven Design", "bounded context", "aggregate", "value object", "domain event", "ubiquitous language", "aggregate root", "domain service" DO NOT USE FOR: database schema design - use database skills; CQRS/Event Sourcing specifics - use `event-sourcing-cqrs`

GitHub
安装命令
npx skhub add claude-dev-suite/ddd
Markdown
SKILL.md

Domain-Driven Design

Strategic DDD

┌─────────────────┐     ┌─────────────────┐
│  Order Context   │────▶│ Payment Context  │
│  (core domain)   │     │  (supporting)    │
└────────┬────────┘     └─────────────────┘
         │
         ▼
┌─────────────────┐     ┌─────────────────┐
│ Inventory Context│     │ Notification Ctx  │
│  (supporting)    │     │  (generic)       │
└─────────────────┘     └─────────────────┘

Tactical DDD (TypeScript)

Entity

class Order {
  private constructor(
    readonly id: OrderId,
    private items: OrderItem[],
    private status: OrderStatus,
    private readonly createdAt: Date,
  ) {}

  static create(items: OrderItem[]): Order {
    if (items.length === 0) throw new DomainError('Order must have at least one item');
    return new Order(OrderId.generate(), items, OrderStatus.PENDING, new Date());
  }

  get total(): Money {
    return this.items.reduce((sum, item) => sum.add(item.subtotal), Money.zero('USD'));
  }

  confirm(): DomainEvent[] {
    if (this.status !== OrderStatus.PENDING) throw new DomainError('Can only confirm pending orders');
    this.status = OrderStatus.CONFIRMED;
    return [new OrderConfirmed(this.id, this.total)];
  }
}

Value Object

class Money {
  private constructor(readonly amount: number, readonly currency: string) {
    if (amount < 0) throw new DomainError('Amount cannot be negative');
  }

  static of(amount: number, currency: string): Money {
    return new Money(Math.round(amount * 100) / 100, currency);
  }

  static zero(currency: string): Money { return new Money(0, currency); }

  add(other: Money): Money {
    if (this.currency !== other.currency) throw new DomainError('Currency mismatch');
    return Money.of(this.amount + other.amount, this.currency);
  }

  equals(other: Money): boolean {
    return this.amount === other.amount && this.currency === other.currency;
  }
}

Domain Event

class OrderConfirmed implements DomainEvent {
  readonly occurredAt = new Date();
  constructor(readonly orderId: OrderId, readonly total: Money) {}
}

Repository (Port)

interface OrderRepository {
  findById(id: OrderId): Promise<Order | null>;
  save(order: Order): Promise<void>;
  nextId(): OrderId;
}

Application Service

class ConfirmOrderUseCase {
  constructor(
    private orders: OrderRepository,
    private eventBus: EventBus,
  ) {}

  async execute(orderId: string): Promise<void> {
    const order = await this.orders.findById(OrderId.from(orderId));
    if (!order) throw new NotFoundError('Order', orderId);

    const events = order.confirm();
    await this.orders.save(order);
    await this.eventBus.publishAll(events);
  }
}

DDD Building Blocks

Building BlockPurposeIdentity?Mutable?
EntityDomain object with identityYes (ID)Yes
Value ObjectImmutable descriptorNo (structural equality)No
AggregateConsistency boundaryRoot entity has IDYes (via root)
Domain EventSomething that happenedEvent IDNo
RepositoryPersistence abstractionN/AN/A
Domain ServiceLogic not belonging to entityN/AN/A

Anti-Patterns

Anti-PatternFix
Anemic domain model (logic in services)Put business logic in entities
Aggregate too largeKeep aggregates small, reference by ID
Exposing entity internalsUse methods that express domain intent
Cross-aggregate transactionsUse domain events for eventual consistency
Repository returning DTOsReturn domain objects, map in application layer

Production Checklist

  • Bounded contexts identified and documented
  • Ubiquitous language in code matches business terms
  • Aggregates enforce invariants
  • Value objects for all descriptors (Money, Email, Address)
  • Domain events for cross-context communication
  • Repository pattern for persistence abstraction
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

skills/architecture/ddd

默认分支

main

最新提交

9496306

Tree SHA

fe4e2f1