ddd

📁 jackjin1997/clawforge 📅 12 days ago
4
总安装量
4
周安装量
#50951
全站排名
安装命令
npx skills add https://github.com/jackjin1997/clawforge --skill ddd

Agent 安装分布

openclaw 4
github-copilot 4
codex 4
kimi-cli 4
gemini-cli 4
cursor 4

Skill 文档

DDD Skill – 领域驱动设计建模

概述

DDD Skill 提供领域驱动设计的完整指导,帮助开发者和架构师进行领域建模、限界上下文划分和战术模式实现。

何时使用

当用户需要:

  • 分析复杂业务领域并进行领域建模
  • 划分限界上下文和子域
  • 设计聚合根、实体、值对象
  • 实现领域服务和领域事件
  • 进行微服务边界划分
  • 应用CQRS/事件溯源模式
  • 设计六边形架构/洋葱架构

快速开始

1. 战略设计(Strategic Design)

确定业务领域的边界和上下文关系:

核心域(Core Domain)→ 竞争优势所在
支撑域(Supporting Domain)→ 支持核心业务
通用域(Generic Domain)→ 可外购/复用

2. 战术设计(Tactical Design)

在限界上下文内进行详细建模:

聚合根(Aggregate Root)
├── 实体(Entity)- 有唯一标识
├── 值对象(Value Object)- 无标识,不可变
└── 领域事件(Domain Event)- 记录业务变化

核心概念

限界上下文(Bounded Context)

限界上下文是DDD的核心概念,定义了领域模型的边界:

┌─────────────────────────────────────────────────────┐
│                    订单上下文                         │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐              │
│  │  订单   │  │ 订单项  │  │ 支付    │              │
│  │ 聚合根  │  │  实体   │  │ 值对象  │              │
│  └─────────┘  └─────────┘  └─────────┘              │
└─────────────────────────────────────────────────────┘
                    │
                    │ 上下文映射
                    ▼
┌─────────────────────────────────────────────────────┐
│                    库存上下文                         │
│  ┌─────────┐  ┌─────────┐                           │
│  │  库存   │  │ 库存项  │                           │
│  │ 聚合根  │  │  实体   │                           │
│  └─────────┘  └─────────┘                           │
└─────────────────────────────────────────────────────┘

聚合设计规则

  1. 保护业务不变式 – 聚合边界内的数据一致性由聚合根保护
  2. 小聚合原则 – 聚合应尽可能小,只包含必需的元素
  3. 通过ID引用 – 聚合间通过ID引用,不直接持有对象引用
  4. 一次事务一个聚合 – 每次事务只修改一个聚合
  5. 最终一致性 – 聚合间通过领域事件实现最终一致性

建模工作流

步骤1:事件风暴(Event Storming)

识别领域中的关键事件:

橙色便签:领域事件(发生了什么)
蓝色便签:命令(触发事件的动作)
黄色便签:聚合(处理命令、产生事件)
紫色便签:策略(响应事件的规则)
粉色便签:外部系统

步骤2:识别限界上下文

根据事件风暴结果划分上下文边界:

  • 相关事件和聚合归入同一上下文
  • 使用通用语言(Ubiquitous Language)
  • 确定上下文之间的关系

步骤3:上下文映射

定义上下文间的集成关系:

模式 说明 适用场景
共享内核 共享部分模型 紧密协作团队
客户-供应商 上下游依赖 明确的服务依赖
防腐层 隔离外部模型 集成遗留系统
开放主机服务 提供标准API 多消费者场景
发布语言 共享数据格式 事件驱动集成

步骤4:战术建模

在每个上下文内进行详细设计:

# 聚合根示例
class Order(AggregateRoot):
    def __init__(self, order_id: OrderId, customer_id: CustomerId):
        self.id = order_id
        self.customer_id = customer_id
        self.items: List[OrderItem] = []
        self.status = OrderStatus.DRAFT
    
    def add_item(self, product_id: ProductId, quantity: int, price: Money):
        """添加订单项 - 业务逻辑封装在聚合内"""
        if self.status != OrderStatus.DRAFT:
            raise DomainException("只能向草稿订单添加商品")
        item = OrderItem(product_id, quantity, price)
        self.items.append(item)
        self.add_event(OrderItemAdded(self.id, item))
    
    def submit(self):
        """提交订单 - 触发领域事件"""
        if not self.items:
            raise DomainException("订单不能为空")
        self.status = OrderStatus.SUBMITTED
        self.add_event(OrderSubmitted(self.id, self.total_amount))
# 值对象示例 - 不可变,无标识
@dataclass(frozen=True)
class Money:
    amount: Decimal
    currency: str
    
    def add(self, other: 'Money') -> 'Money':
        if self.currency != other.currency:
            raise ValueError("货币类型不匹配")
        return Money(self.amount + other.amount, self.currency)
# 领域事件示例
@dataclass(frozen=True)
class OrderSubmitted(DomainEvent):
    order_id: OrderId
    total_amount: Money
    occurred_at: datetime = field(default_factory=datetime.utcnow)

架构模式

六边形架构(端口与适配器)

                    ┌─────────────────────────────────┐
                    │         应用层(Application)    │
    ┌───────────┐   │  ┌─────────────────────────┐   │   ┌───────────┐
    │   REST    │◄──┼──│      端口(Ports)       │──┼──►│  数据库   │
    │   API     │   │  └─────────────────────────┘   │   │ 适配器    │
    └───────────┘   │              │                  │   └───────────┘
                    │              ▼                  │
    ┌───────────┐   │  ┌─────────────────────────┐   │   ┌───────────┐
    │  消息     │◄──┼──│      领域层(Domain)    │──┼──►│  消息     │
    │  队列     │   │  │    聚合、实体、值对象     │   │   │ 适配器    │
    └───────────┘   │  └─────────────────────────┘   │   └───────────┘
                    └─────────────────────────────────┘

CQRS模式

命令端(Command Side)          查询端(Query Side)
      │                              │
      ▼                              ▼
┌──────────────┐              ┌──────────────┐
│ Command Bus  │              │  Query Bus   │
└──────────────┘              └──────────────┘
      │                              │
      ▼                              ▼
┌──────────────┐              ┌──────────────┐
│   聚合根     │──事件──►     │   读模型     │
│(写模型)    │              │(优化查询)  │
└──────────────┘              └──────────────┘
      │                              │
      ▼                              ▼
┌──────────────┐              ┌──────────────┐
│  事件存储    │              │  查询数据库  │
└──────────────┘              └──────────────┘

资源文件

详细参考文档:

  • references/strategic-design.md – 战略设计详解
  • references/tactical-design.md – 战术设计模式
  • references/patterns.md – DDD架构模式
  • assets/ddd-model-template.drawio – 领域模型模板

常见问题

Q: 如何确定聚合边界?

  1. 识别业务不变式(必须始终为真的规则)
  2. 不变式涉及的实体应在同一聚合内
  3. 优先小聚合,通过领域事件实现跨聚合一致性

Q: 何时使用领域服务?

  • 业务逻辑不自然属于任何实体或值对象
  • 需要协调多个聚合的操作
  • 例如:转账服务(协调两个账户聚合)

Q: 如何处理跨聚合事务?

  • 使用Saga模式编排长事务
  • 通过领域事件实现最终一致性
  • 避免分布式事务,拥抱补偿机制

相关链接