5.1.3 领域驱动设计 DDD

5.1.3 领域驱动设计 DDD #

领域驱动设计(Domain-Driven Design,DDD)是一种软件开发方法论,它强调将业务领域的复杂性作为软件设计的核心。在微服务架构中,DDD 提供了清晰的指导原则来划分服务边界和设计服务内部结构。

DDD 核心概念 #

1. 领域(Domain) #

领域是组织所从事的业务活动范围:

// 电商领域的定义
type EcommerceDomain struct {
    Name        string
    Description string
    Subdomains  []Subdomain
}

type Subdomain struct {
    Name        string
    Type        SubdomainType // Core, Supporting, Generic
    Description string
    Complexity  int // 1-10
    Strategic   bool
}

type SubdomainType string

const (
    CoreSubdomain       SubdomainType = "core"
    SupportingSubdomain SubdomainType = "supporting"
    GenericSubdomain    SubdomainType = "generic"
)

// 电商领域的子域划分
var ecommerceDomain = EcommerceDomain{
    Name:        "电商平台",
    Description: "在线购物和交易平台",
    Subdomains: []Subdomain{
        {
            Name:        "商品管理",
            Type:        CoreSubdomain,
            Description: "商品信息、分类、库存管理",
            Complexity:  8,
            Strategic:   true,
        },
        {
            Name:        "订单处理",
            Type:        CoreSubdomain,
            Description: "订单生命周期管理",
            Complexity:  9,
            Strategic:   true,
        },
        {
            Name:        "用户管理",
            Type:        SupportingSubdomain,
            Description: "用户账户和认证",
            Complexity:  6,
            Strategic:   false,
        },
        {
            Name:        "支付处理",
            Type:        GenericSubdomain,
            Description: "支付网关集成",
            Complexity:  4,
            Strategic:   false,
        },
    },
}

2. 限界上下文(Bounded Context) #

限界上下文定义了模型的边界:

// 限界上下文定义
type BoundedContext struct {
    Name         string
    Domain       string
    Subdomain    string
    Team         string
    Language     UbiquitousLanguage
    Models       []DomainModel
    Services     []DomainService
    Repositories []Repository
    Events       []DomainEvent
}

type UbiquitousLanguage map[string]string

// 订单上下文
var orderContext = BoundedContext{
    Name:      "订单上下文",
    Domain:    "电商平台",
    Subdomain: "订单处理",
    Team:      "订单团队",
    Language: UbiquitousLanguage{
        "订单":   "Order - 客户的购买请求",
        "订单项": "OrderItem - 订单中的具体商品",
        "订单状态": "OrderStatus - 订单的当前状态",
        "发货":   "Shipment - 订单的物流配送",
    },
    Models: []DomainModel{
        {Name: "Order", Type: "AggregateRoot"},
        {Name: "OrderItem", Type: "Entity"},
        {Name: "OrderStatus", Type: "ValueObject"},
    },
}

// 商品上下文
var productContext = BoundedContext{
    Name:      "商品上下文",
    Domain:    "电商平台",
    Subdomain: "商品管理",
    Team:      "商品团队",
    Language: UbiquitousLanguage{
        "商品":   "Product - 可销售的物品",
        "分类":   "Category - 商品的分类体系",
        "库存":   "Inventory - 商品的可用数量",
        "价格":   "Price - 商品的售价",
    },
    Models: []DomainModel{
        {Name: "Product", Type: "AggregateRoot"},
        {Name: "Category", Type: "Entity"},
        {Name: "Price", Type: "ValueObject"},
    },
}

3. 聚合(Aggregate) #

聚合是一组相关对象的集合,作为数据修改的单元:

// 订单聚合根
type Order struct {
    // 聚合根标识
    id          OrderID
    customerID  CustomerID
    items       []OrderItem
    status      OrderStatus
    totalAmount Money
    createdAt   time.Time
    updatedAt   time.Time

    // 领域事件
    events []DomainEvent
}

// 订单ID值对象
type OrderID struct {
    value int64
}

func (id OrderID) Value() int64 {
    return id.value
}

func (id OrderID) String() string {
    return fmt.Sprintf("ORDER-%d", id.value)
}

// 订单项实体
type OrderItem struct {
    id        OrderItemID
    productID ProductID
    quantity  Quantity
    price     Money
    subtotal  Money
}

// 订单状态值对象
type OrderStatus struct {
    value string
}

func (s OrderStatus) String() string {
    return s.value
}

func (s OrderStatus) IsValid() bool {
    validStatuses := []string{"pending", "confirmed", "shipped", "delivered", "cancelled"}
    for _, status := range validStatuses {
        if s.value == status {
            return true
        }
    }
    return false
}

// 金额值对象
type Money struct {
    amount   float64
    currency string
}

func (m Money) Add(other Money) (Money, error) {
    if m.currency != other.currency {
        return Money{}, errors.New("cannot add different currencies")
    }
    return Money{
        amount:   m.amount + other.amount,
        currency: m.currency,
    }, nil
}

func (m Money) Multiply(factor float64) Money {
    return Money{
        amount:   m.amount * factor,
        currency: m.currency,
    }
}

// 订单聚合的业务方法
func (o *Order) AddItem(productID ProductID, quantity Quantity, price Money) error {
    // 业务规则验证
    if o.status.value != "pending" {
        return errors.New("cannot add items to non-pending order")
    }

    if quantity.value <= 0 {
        return errors.New("quantity must be positive")
    }

    // 检查是否已存在相同商品
    for i, item := range o.items {
        if item.productID.Equals(productID) {
            // 更新数量
            newQuantity := Quantity{value: item.quantity.value + quantity.value}
            o.items[i].quantity = newQuantity
            o.items[i].subtotal = price.Multiply(float64(newQuantity.value))
            o.recalculateTotal()
            return nil
        }
    }

    // 添加新订单项
    item := OrderItem{
        id:        NewOrderItemID(),
        productID: productID,
        quantity:  quantity,
        price:     price,
        subtotal:  price.Multiply(float64(quantity.value)),
    }

    o.items = append(o.items, item)
    o.recalculateTotal()
    o.updatedAt = time.Now()

    // 发布领域事件
    event := OrderItemAddedEvent{
        OrderID:   o.id,
        ProductID: productID,
        Quantity:  quantity,
        Price:     price,
        Timestamp: time.Now(),
    }
    o.addEvent(event)

    return nil
}

func (o *Order) Confirm() error {
    if o.status.value != "pending" {
        return errors.New("only pending orders can be confirmed")
    }

    if len(o.items) == 0 {
        return errors.New("cannot confirm empty order")
    }

    o.status = OrderStatus{value: "confirmed"}
    o.updatedAt = time.Now()

    // 发布订单确认事件
    event := OrderConfirmedEvent{
        OrderID:     o.id,
        CustomerID:  o.customerID,
        TotalAmount: o.totalAmount,
        Items:       o.items,
        Timestamp:   time.Now(),
    }
    o.addEvent(event)

    return nil
}

func (o *Order) recalculateTotal() {
    total := Money{amount: 0, currency: "CNY"}
    for _, item := range o.items {
        total, _ = total.Add(item.subtotal)
    }
    o.totalAmount = total
}

func (o *Order) addEvent(event DomainEvent) {
    o.events = append(o.events, event)
}

func (o *Order) GetEvents() []DomainEvent {
    return o.events
}

func (o *Order) ClearEvents() {
    o.events = nil
}

4. 领域服务(Domain Service) #

处理不属于任何实体或值对象的业务逻辑:

// 订单定价服务
type OrderPricingService struct {
    promotionRepo PromotionRepository
    taxService    TaxService
}

func (s *OrderPricingService) CalculateOrderPrice(order *Order, customer *Customer) (*PricingResult, error) {
    result := &PricingResult{
        BaseAmount:    order.totalAmount,
        DiscountAmount: Money{amount: 0, currency: "CNY"},
        TaxAmount:     Money{amount: 0, currency: "CNY"},
    }

    // 应用促销折扣
    promotions, err := s.promotionRepo.FindApplicablePromotions(customer.ID, order.items)
    if err != nil {
        return nil, err
    }

    for _, promotion := range promotions {
        discount := s.calculateDiscount(promotion, order)
        result.DiscountAmount, _ = result.DiscountAmount.Add(discount)
    }

    // 计算税费
    taxableAmount, _ := result.BaseAmount.Add(result.DiscountAmount.Multiply(-1))
    tax, err := s.taxService.CalculateTax(taxableAmount, customer.Address)
    if err != nil {
        return nil, err
    }
    result.TaxAmount = tax

    // 计算最终金额
    finalAmount, _ := result.BaseAmount.Add(result.DiscountAmount.Multiply(-1))
    result.FinalAmount, _ = finalAmount.Add(result.TaxAmount)

    return result, nil
}

type PricingResult struct {
    BaseAmount     Money
    DiscountAmount Money
    TaxAmount      Money
    FinalAmount    Money
}

// 库存分配服务
type InventoryAllocationService struct {
    inventoryRepo InventoryRepository
    warehouseRepo WarehouseRepository
}

func (s *InventoryAllocationService) AllocateInventory(order *Order) (*AllocationResult, error) {
    result := &AllocationResult{
        Allocations: make([]ItemAllocation, 0),
        Successful:  true,
    }

    for _, item := range order.items {
        allocation, err := s.allocateItem(item)
        if err != nil {
            result.Successful = false
            result.FailureReason = err.Error()
            return result, err
        }
        result.Allocations = append(result.Allocations, allocation)
    }

    return result, nil
}

func (s *InventoryAllocationService) allocateItem(item OrderItem) (ItemAllocation, error) {
    // 查找可用库存
    inventories, err := s.inventoryRepo.FindAvailableInventory(item.productID)
    if err != nil {
        return ItemAllocation{}, err
    }

    // 按优先级分配库存
    allocation := ItemAllocation{
        ProductID: item.productID,
        Quantity:  item.quantity,
        Sources:   make([]InventorySource, 0),
    }

    remainingQuantity := item.quantity.value
    for _, inventory := range inventories {
        if remainingQuantity <= 0 {
            break
        }

        allocatedQuantity := min(remainingQuantity, inventory.AvailableQuantity)
        source := InventorySource{
            WarehouseID: inventory.WarehouseID,
            Quantity:    Quantity{value: allocatedQuantity},
        }
        allocation.Sources = append(allocation.Sources, source)
        remainingQuantity -= allocatedQuantity
    }

    if remainingQuantity > 0 {
        return ItemAllocation{}, fmt.Errorf("insufficient inventory for product %s", item.productID)
    }

    return allocation, nil
}

type AllocationResult struct {
    Allocations   []ItemAllocation
    Successful    bool
    FailureReason string
}

type ItemAllocation struct {
    ProductID ProductID
    Quantity  Quantity
    Sources   []InventorySource
}

type InventorySource struct {
    WarehouseID WarehouseID
    Quantity    Quantity
}

5. 领域事件(Domain Event) #

表示领域中发生的重要业务事件:

// 领域事件接口
type DomainEvent interface {
    EventID() string
    EventType() string
    AggregateID() string
    OccurredOn() time.Time
    EventVersion() int
}

// 基础事件结构
type BaseEvent struct {
    id          string
    eventType   string
    aggregateID string
    occurredOn  time.Time
    version     int
}

func (e BaseEvent) EventID() string     { return e.id }
func (e BaseEvent) EventType() string   { return e.eventType }
func (e BaseEvent) AggregateID() string { return e.aggregateID }
func (e BaseEvent) OccurredOn() time.Time { return e.occurredOn }
func (e BaseEvent) EventVersion() int   { return e.version }

// 订单确认事件
type OrderConfirmedEvent struct {
    BaseEvent
    CustomerID  CustomerID
    TotalAmount Money
    Items       []OrderItem
}

func NewOrderConfirmedEvent(orderID OrderID, customerID CustomerID, totalAmount Money, items []OrderItem) OrderConfirmedEvent {
    return OrderConfirmedEvent{
        BaseEvent: BaseEvent{
            id:          generateEventID(),
            eventType:   "OrderConfirmed",
            aggregateID: orderID.String(),
            occurredOn:  time.Now(),
            version:     1,
        },
        CustomerID:  customerID,
        TotalAmount: totalAmount,
        Items:       items,
    }
}

// 商品库存变更事件
type InventoryChangedEvent struct {
    BaseEvent
    ProductID       ProductID
    WarehouseID     WarehouseID
    PreviousQuantity Quantity
    NewQuantity     Quantity
    ChangeReason    string
}

// 事件发布器
type EventPublisher interface {
    Publish(ctx context.Context, event DomainEvent) error
    PublishBatch(ctx context.Context, events []DomainEvent) error
}

// 事件处理器
type EventHandler interface {
    Handle(ctx context.Context, event DomainEvent) error
    EventType() string
}

// 订单确认事件处理器
type OrderConfirmedEventHandler struct {
    inventoryService InventoryService
    emailService     EmailService
    logger          *log.Logger
}

func (h *OrderConfirmedEventHandler) Handle(ctx context.Context, event DomainEvent) error {
    orderEvent, ok := event.(OrderConfirmedEvent)
    if !ok {
        return errors.New("invalid event type")
    }

    // 扣减库存
    for _, item := range orderEvent.Items {
        if err := h.inventoryService.ReserveInventory(ctx, item.productID, item.quantity); err != nil {
            h.logger.Errorf("Failed to reserve inventory for product %s: %v", item.productID, err)
            // 这里可能需要补偿机制
        }
    }

    // 发送确认邮件
    if err := h.emailService.SendOrderConfirmation(ctx, orderEvent.CustomerID, orderEvent.AggregateID); err != nil {
        h.logger.Errorf("Failed to send order confirmation email: %v", err)
        // 邮件发送失败不影响主流程
    }

    return nil
}

func (h *OrderConfirmedEventHandler) EventType() string {
    return "OrderConfirmed"
}

DDD 在微服务中的应用 #

1. 基于限界上下文的服务划分 #

// 基于DDD的微服务架构
type MicroserviceArchitecture struct {
    Services []MicroserviceDefinition
}

type MicroserviceDefinition struct {
    Name            string
    BoundedContext  string
    Team            string
    Aggregates      []string
    DomainServices  []string
    ApplicationServices []string
    Infrastructure  InfrastructureConfig
}

type InfrastructureConfig struct {
    Database    DatabaseConfig
    MessageQueue MessageQueueConfig
    Cache       CacheConfig
}

// 订单微服务定义
var orderMicroservice = MicroserviceDefinition{
    Name:           "order-service",
    BoundedContext: "订单上下文",
    Team:           "订单团队",
    Aggregates:     []string{"Order", "Shipment"},
    DomainServices: []string{"OrderPricingService", "InventoryAllocationService"},
    ApplicationServices: []string{"OrderApplicationService", "OrderQueryService"},
    Infrastructure: InfrastructureConfig{
        Database: DatabaseConfig{
            Type: "PostgreSQL",
            Name: "order_db",
        },
        MessageQueue: MessageQueueConfig{
            Type: "Kafka",
            Topics: []string{"order.events", "inventory.events"},
        },
        Cache: CacheConfig{
            Type: "Redis",
            TTL:  "30m",
        },
    },
}

// 商品微服务定义
var productMicroservice = MicroserviceDefinition{
    Name:           "product-service",
    BoundedContext: "商品上下文",
    Team:           "商品团队",
    Aggregates:     []string{"Product", "Category", "Inventory"},
    DomainServices: []string{"ProductSearchService", "PricingService"},
    ApplicationServices: []string{"ProductApplicationService", "ProductQueryService"},
    Infrastructure: InfrastructureConfig{
        Database: DatabaseConfig{
            Type: "MongoDB",
            Name: "product_db",
        },
        MessageQueue: MessageQueueConfig{
            Type: "Kafka",
            Topics: []string{"product.events", "inventory.events"},
        },
        Cache: CacheConfig{
            Type: "Redis",
            TTL:  "1h",
        },
    },
}

2. 应用服务层设计 #

应用服务协调领域对象完成业务用例:

// 订单应用服务
type OrderApplicationService struct {
    orderRepo        OrderRepository
    customerRepo     CustomerRepository
    productRepo      ProductRepository
    pricingService   *OrderPricingService
    allocationService *InventoryAllocationService
    eventPublisher   EventPublisher
    unitOfWork       UnitOfWork
}

// 创建订单用例
func (s *OrderApplicationService) CreateOrder(ctx context.Context, cmd CreateOrderCommand) (*OrderDTO, error) {
    // 开始工作单元
    uow := s.unitOfWork.Begin()
    defer func() {
        if r := recover(); r != nil {
            uow.Rollback()
            panic(r)
        }
    }()

    // 验证客户
    customer, err := s.customerRepo.FindByID(ctx, cmd.CustomerID)
    if err != nil {
        uow.Rollback()
        return nil, fmt.Errorf("customer not found: %w", err)
    }

    // 验证商品
    var orderItems []OrderItem
    for _, item := range cmd.Items {
        product, err := s.productRepo.FindByID(ctx, item.ProductID)
        if err != nil {
            uow.Rollback()
            return nil, fmt.Errorf("product not found: %w", err)
        }

        orderItem := OrderItem{
            id:        NewOrderItemID(),
            productID: item.ProductID,
            quantity:  Quantity{value: item.Quantity},
            price:     Money{amount: product.Price, currency: "CNY"},
        }
        orderItems = append(orderItems, orderItem)
    }

    // 创建订单聚合
    order := NewOrder(NewOrderID(), cmd.CustomerID)
    for _, item := range orderItems {
        if err := order.AddItem(item.productID, item.quantity, item.price); err != nil {
            uow.Rollback()
            return nil, err
        }
    }

    // 计算价格
    pricingResult, err := s.pricingService.CalculateOrderPrice(order, customer)
    if err != nil {
        uow.Rollback()
        return nil, fmt.Errorf("pricing calculation failed: %w", err)
    }

    // 分配库存
    allocationResult, err := s.allocationService.AllocateInventory(order)
    if err != nil {
        uow.Rollback()
        return nil, fmt.Errorf("inventory allocation failed: %w", err)
    }

    // 保存订单
    if err := s.orderRepo.Save(ctx, order); err != nil {
        uow.Rollback()
        return nil, fmt.Errorf("failed to save order: %w", err)
    }

    // 发布领域事件
    events := order.GetEvents()
    for _, event := range events {
        if err := s.eventPublisher.Publish(ctx, event); err != nil {
            // 事件发布失败不回滚事务,但需要记录
            log.Errorf("Failed to publish event %s: %v", event.EventType(), err)
        }
    }

    // 提交工作单元
    if err := uow.Commit(); err != nil {
        return nil, fmt.Errorf("failed to commit transaction: %w", err)
    }

    // 清除事件
    order.ClearEvents()

    return s.toOrderDTO(order, pricingResult, allocationResult), nil
}

// 命令对象
type CreateOrderCommand struct {
    CustomerID CustomerID
    Items      []CreateOrderItemCommand
}

type CreateOrderItemCommand struct {
    ProductID ProductID
    Quantity  int
}

// DTO对象
type OrderDTO struct {
    ID          string           `json:"id"`
    CustomerID  string           `json:"customer_id"`
    Items       []OrderItemDTO   `json:"items"`
    Status      string           `json:"status"`
    TotalAmount MoneyDTO         `json:"total_amount"`
    CreatedAt   time.Time        `json:"created_at"`
}

type OrderItemDTO struct {
    ID        string   `json:"id"`
    ProductID string   `json:"product_id"`
    Quantity  int      `json:"quantity"`
    Price     MoneyDTO `json:"price"`
    Subtotal  MoneyDTO `json:"subtotal"`
}

type MoneyDTO struct {
    Amount   float64 `json:"amount"`
    Currency string  `json:"currency"`
}

func (s *OrderApplicationService) toOrderDTO(order *Order, pricing *PricingResult, allocation *AllocationResult) *OrderDTO {
    dto := &OrderDTO{
        ID:         order.id.String(),
        CustomerID: order.customerID.String(),
        Status:     order.status.String(),
        TotalAmount: MoneyDTO{
            Amount:   pricing.FinalAmount.amount,
            Currency: pricing.FinalAmount.currency,
        },
        CreatedAt: order.createdAt,
        Items:     make([]OrderItemDTO, len(order.items)),
    }

    for i, item := range order.items {
        dto.Items[i] = OrderItemDTO{
            ID:        item.id.String(),
            ProductID: item.productID.String(),
            Quantity:  item.quantity.value,
            Price: MoneyDTO{
                Amount:   item.price.amount,
                Currency: item.price.currency,
            },
            Subtotal: MoneyDTO{
                Amount:   item.subtotal.amount,
                Currency: item.subtotal.currency,
            },
        }
    }

    return dto
}

3. 仓储模式实现 #

// 订单仓储接口
type OrderRepository interface {
    FindByID(ctx context.Context, id OrderID) (*Order, error)
    FindByCustomerID(ctx context.Context, customerID CustomerID) ([]*Order, error)
    Save(ctx context.Context, order *Order) error
    Delete(ctx context.Context, id OrderID) error
}

// 订单仓储实现
type PostgreSQLOrderRepository struct {
    db *gorm.DB
}

func (r *PostgreSQLOrderRepository) FindByID(ctx context.Context, id OrderID) (*Order, error) {
    var orderPO OrderPO
    if err := r.db.WithContext(ctx).Preload("Items").First(&orderPO, id.Value()).Error; err != nil {
        if errors.Is(err, gorm.ErrRecordNotFound) {
            return nil, ErrOrderNotFound
        }
        return nil, err
    }

    return r.toDomainModel(orderPO), nil
}

func (r *PostgreSQLOrderRepository) Save(ctx context.Context, order *Order) error {
    orderPO := r.toPersistenceModel(order)

    return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
        // 保存订单
        if err := tx.Save(&orderPO).Error; err != nil {
            return err
        }

        // 删除旧的订单项
        if err := tx.Where("order_id = ?", orderPO.ID).Delete(&OrderItemPO{}).Error; err != nil {
            return err
        }

        // 保存新的订单项
        for _, item := range orderPO.Items {
            item.OrderID = orderPO.ID
            if err := tx.Create(&item).Error; err != nil {
                return err
            }
        }

        return nil
    })
}

// 持久化对象
type OrderPO struct {
    ID          int64         `gorm:"primaryKey"`
    CustomerID  int64         `gorm:"not null"`
    Status      string        `gorm:"not null"`
    TotalAmount float64       `gorm:"not null"`
    Currency    string        `gorm:"not null"`
    CreatedAt   time.Time     `gorm:"not null"`
    UpdatedAt   time.Time     `gorm:"not null"`
    Items       []OrderItemPO `gorm:"foreignKey:OrderID"`
}

type OrderItemPO struct {
    ID        int64   `gorm:"primaryKey"`
    OrderID   int64   `gorm:"not null"`
    ProductID int64   `gorm:"not null"`
    Quantity  int     `gorm:"not null"`
    Price     float64 `gorm:"not null"`
    Currency  string  `gorm:"not null"`
    Subtotal  float64 `gorm:"not null"`
}

// 领域模型转换
func (r *PostgreSQLOrderRepository) toDomainModel(po OrderPO) *Order {
    items := make([]OrderItem, len(po.Items))
    for i, itemPO := range po.Items {
        items[i] = OrderItem{
            id:        OrderItemID{value: itemPO.ID},
            productID: ProductID{value: itemPO.ProductID},
            quantity:  Quantity{value: itemPO.Quantity},
            price:     Money{amount: itemPO.Price, currency: itemPO.Currency},
            subtotal:  Money{amount: itemPO.Subtotal, currency: itemPO.Currency},
        }
    }

    return &Order{
        id:          OrderID{value: po.ID},
        customerID:  CustomerID{value: po.CustomerID},
        items:       items,
        status:      OrderStatus{value: po.Status},
        totalAmount: Money{amount: po.TotalAmount, currency: po.Currency},
        createdAt:   po.CreatedAt,
        updatedAt:   po.UpdatedAt,
        events:      make([]DomainEvent, 0),
    }
}

func (r *PostgreSQLOrderRepository) toPersistenceModel(order *Order) OrderPO {
    items := make([]OrderItemPO, len(order.items))
    for i, item := range order.items {
        items[i] = OrderItemPO{
            ID:        item.id.value,
            ProductID: item.productID.value,
            Quantity:  item.quantity.value,
            Price:     item.price.amount,
            Currency:  item.price.currency,
            Subtotal:  item.subtotal.amount,
        }
    }

    return OrderPO{
        ID:          order.id.value,
        CustomerID:  order.customerID.value,
        Status:      order.status.value,
        TotalAmount: order.totalAmount.amount,
        Currency:    order.totalAmount.currency,
        CreatedAt:   order.createdAt,
        UpdatedAt:   order.updatedAt,
        Items:       items,
    }
}

4. 工作单元模式 #

// 工作单元接口
type UnitOfWork interface {
    Begin() UnitOfWork
    Commit() error
    Rollback() error
    RegisterNew(entity interface{})
    RegisterDirty(entity interface{})
    RegisterDeleted(entity interface{})
}

// 工作单元实现
type GormUnitOfWork struct {
    db      *gorm.DB
    tx      *gorm.DB
    newEntities     []interface{}
    dirtyEntities   []interface{}
    deletedEntities []interface{}
}

func NewGormUnitOfWork(db *gorm.DB) *GormUnitOfWork {
    return &GormUnitOfWork{
        db: db,
        newEntities:     make([]interface{}, 0),
        dirtyEntities:   make([]interface{}, 0),
        deletedEntities: make([]interface{}, 0),
    }
}

func (uow *GormUnitOfWork) Begin() UnitOfWork {
    uow.tx = uow.db.Begin()
    return uow
}

func (uow *GormUnitOfWork) Commit() error {
    if uow.tx == nil {
        return errors.New("transaction not started")
    }

    // 处理新实体
    for _, entity := range uow.newEntities {
        if err := uow.tx.Create(entity).Error; err != nil {
            uow.tx.Rollback()
            return err
        }
    }

    // 处理修改的实体
    for _, entity := range uow.dirtyEntities {
        if err := uow.tx.Save(entity).Error; err != nil {
            uow.tx.Rollback()
            return err
        }
    }

    // 处理删除的实体
    for _, entity := range uow.deletedEntities {
        if err := uow.tx.Delete(entity).Error; err != nil {
            uow.tx.Rollback()
            return err
        }
    }

    return uow.tx.Commit().Error
}

func (uow *GormUnitOfWork) Rollback() error {
    if uow.tx == nil {
        return nil
    }
    return uow.tx.Rollback().Error
}

func (uow *GormUnitOfWork) RegisterNew(entity interface{}) {
    uow.newEntities = append(uow.newEntities, entity)
}

func (uow *GormUnitOfWork) RegisterDirty(entity interface{}) {
    uow.dirtyEntities = append(uow.dirtyEntities, entity)
}

func (uow *GormUnitOfWork) RegisterDeleted(entity interface{}) {
    uow.deletedEntities = append(uow.deletedEntities, entity)
}

通过本节的学习,我们深入了解了如何运用领域驱动设计来指导微服务的架构设计。DDD 提供了清晰的方法论来识别服务边界、设计领域模型和组织代码结构,是构建复杂微服务系统的重要指导原则。在下一节中,我们将学习微服务间的通信模式和实现方法。