← 返回首页
🎯

DDD代码结构

📂 architecture ⏱ 3 min 458 words

DDD代码结构

分层架构

DDD 推荐的分层架构将代码分为领域层、应用层、基础设施层和用户接口层。

项目结构:
order-service/
├── src/main/java/com/example/order/
│   ├── domain/                    # 领域层(核心)
│   │   ├── model/
│   │   │   ├── Order.java         # 聚合根
│   │   │   ├── OrderItem.java     # 实体
│   │   │   ├── OrderId.java       # 值对象
│   │   │   ├── Money.java         # 值对象
│   │   │   └── OrderStatus.java   # 枚举
│   │   ├── repository/
│   │   │   └── OrderRepository.java
│   │   ├── event/
│   │   │   └── OrderCreatedEvent.java
│   │   └── exception/
│   │       └── OrderNotFoundException.java
│   │
│   ├── application/               # 应用层
│   │   ├── service/
│   │   │   └── OrderApplicationService.java
│   │   ├── command/
│   │   │   ├── CreateOrderCommand.java
│   │   │   └── CancelOrderCommand.java
│   │   └── query/
│   │       └── OrderQueryService.java
│   │
│   ├── infrastructure/            # 基础设施层
│   │   ├── persistence/
│   │   │   ├── JpaOrderRepository.java
│   │   │   ├── OrderEntity.java
│   │   │   └── OrderMapper.java
│   │   ├── messaging/
│   │   │   └── OrderEventPublisher.java
│   │   └── config/
│   │       └── PersistenceConfig.java
│   │
│   └── interfaces/                # 用户接口层
│       ├── rest/
│       │   └── OrderController.java
│       └── dto/
│           ├── CreateOrderRequest.java
│           └── OrderResponse.java

聚合根实现

// 聚合根:订单
@Entity
@Table(name = "orders")
public class Order {
    
    @Id
    private Long id;
    
    @Column(name = "order_no")
    private String orderNo;
    
    @Column(name = "customer_id")
    private Long customerId;
    
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
    
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "order_id")
    private List<OrderItem> items = new ArrayList<>();
    
    @Version
    private Long version;  // 乐观锁
    
    private List<DomainEvent> domainEvents = new ArrayList<>();
    
    // 工厂方法
    public static Order create(Long customerId, List<OrderItem> items) {
        Order order = new Order();
        order.id = generateId();
        order.orderNo = generateOrderNo();
        order.customerId = customerId;
        order.status = OrderStatus.CREATED;
        order.items = new ArrayList<>(items);
        
        // 产生领域事件
        order.registerEvent(new OrderCreatedEvent(order.id, order.orderNo));
        
        return order;
    }
    
    // 业务方法
    public void pay(Money amount) {
        if (this.status != OrderStatus.CREATED) {
            throw new InvalidOrderStateException("只有待支付订单可以支付");
        }
        this.status = OrderStatus.PAID;
        registerEvent(new OrderPaidEvent(this.id, amount));
    }
    
    public void cancel() {
        if (this.status == OrderStatus.SHIPPED) {
            throw new InvalidOrderStateException("已发货订单不能取消");
        }
        this.status = OrderStatus.CANCELLED;
        registerEvent(new OrderCancelledEvent(this.id));
    }
    
    // 领域事件管理
    private void registerEvent(DomainEvent event) {
        domainEvents.add(event);
    }
    
    public List<DomainEvent> getDomainEvents() {
        return Collections.unmodifiableList(domainEvents);
    }
    
    public void clearEvents() {
        domainEvents.clear();
    }
}

Repository 实现

// Repository 接口(领域层)
public interface OrderRepository {
    Optional<Order> findById(Long id);
    Optional<Order> findByOrderNo(String orderNo);
    List<Order> findByCustomerId(Long customerId);
    Order save(Order order);
    void deleteById(Long id);
}

// JPA 实现(基础设施层)
@Repository
public class JpaOrderRepository implements OrderRepository {
    
    private final OrderJpaRepository jpaRepository;
    private final OrderMapper mapper;
    
    @Override
    public Optional<Order> findById(Long id) {
        return jpaRepository.findById(id).map(mapper::toDomain);
    }
    
    @Override
    public Order save(Order order) {
        OrderEntity entity = mapper.toEntity(order);
        OrderEntity saved = jpaRepository.save(entity);
        return mapper.toDomain(saved);
    }
}

// Mapper 转换
@Component
public class OrderMapper {
    
    public Order toDomain(OrderEntity entity) {
        Order order = new Order();
        order.setId(entity.getId());
        order.setOrderNo(entity.getOrderNo());
        order.setCustomerId(entity.getCustomerId());
        order.setStatus(entity.getStatus());
        order.setItems(entity.getItems().stream()
            .map(this::toDomainItem)
            .collect(Collectors.toList()));
        return order;
    }
    
    public OrderEntity toEntity(Order order) {
        OrderEntity entity = new OrderEntity();
        entity.setId(order.getId());
        entity.setOrderNo(order.getOrderNo());
        entity.setCustomerId(order.getCustomerId());
        entity.setStatus(order.getStatus());
        entity.setItems(order.getItems().stream()
            .map(this::toEntityItem)
            .collect(Collectors.toList()));
        return entity;
    }
}

DDD 代码结构的核心是让领域层保持纯净,不依赖任何基础设施。