领域驱动设计:DDD实践
领域驱动设计:DDD实践
概述
领域驱动设计(DDD)是以业务领域为中心的设计方法。本教程介绍DDD的概念和实践。
1. DDD核心概念
// DDD核心概念
// 1. 领域(Domain):业务领域
// 2. 限界上下文(Bounded Context):领域边界
// 3. 聚合(Aggregate):一组相关对象
// 4. 聚合根(Aggregate Root):聚合的入口点
// 5. 实体(Entity):具有唯一标识的对象
// 6. 值对象(Value Object):没有唯一标识的对象
// 聚合根
@Entity
public class Order {
@Id
private Long id;
private Long userId;
private List<OrderItem> items;
private OrderStatus status;
public void addItem(OrderItem item) {
this.items.add(item);
}
public void setStatus(OrderStatus status) {
this.status = status;
}
}
// 值对象
@Embeddable
public class Money {
private BigDecimal amount;
private Currency currency;
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new IllegalArgumentException("货币类型不匹配");
}
return new Money(this.amount.add(other.amount), this.currency);
}
}
2. 限界上下文
// 限界上下文划分
// 1. 用户上下文:用户管理
// 2. 订单上下文:订单管理
// 3. 支付上下文:支付管理
// 4. 库存上下文:库存管理
// 上下文映射
// 1. 共享内核:共享部分模型
// 2. 客户-供应商:上游提供,下游消费
// 3. 防腐层:转换模型
// 4. 开放主机服务:提供标准API
// 用户上下文
package com.example.user.context;
@Entity
public class User {
@Id
private Long id;
private String name;
private String email;
}
// 订单上下文
package com.example.order.context;
@Entity
public class Order {
@Id
private Long id;
private Long userId; // 引用用户上下文的ID
private List<OrderItem> items;
}
// 防腐层
@Component
public class UserAntiCorruptionLayer {
public UserDTO toDTO(com.example.user.context.User user) {
UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setName(user.getName());
return dto;
}
}
3. 实际应用示例
领域事件
// 领域事件
public class OrderCreatedEvent {
private Long orderId;
private Long userId;
private LocalDateTime timestamp;
// 构造方法和getter
}
// 事件发布
@Component
public class OrderEventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void publishOrderCreated(Order order) {
OrderCreatedEvent event = new OrderCreatedEvent(order.getId(), order.getUserId());
eventPublisher.publishEvent(event);
}
}
// 事件处理
@Component
public class OrderEventHandler {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// 处理订单创建事件
}
}
仓储模式
// 仓储接口
public interface OrderRepository {
Order findById(Long id);
List<Order> findByUserId(Long userId);
Order save(Order order);
void deleteById(Long id);
}
// 仓储实现
@Repository
public class JpaOrderRepository implements OrderRepository {
@Autowired
private OrderJpaRepository jpaRepository;
@Override
public Order findById(Long id) {
return jpaRepository.findById(id).orElse(null);
}
@Override
public Order save(Order order) {
return jpaRepository.save(order);
}
}
4. 最佳实践
- 深入理解业务:与领域专家密切合作
- 合理划分限界上下文:按业务能力划分
- 使用聚合根:保护聚合内部一致性
- 使用领域事件:实现服务间解耦
- 持续重构:根据业务变化调整模型
总结
领域驱动设计是以业务领域为中心的设计方法。掌握DDD的概念和实践,可以构建可维护、可扩展的业务系统。