DDD战术设计
DDD战术设计
Repository 模式
Repository 封装了聚合的持久化逻辑,提供类集合的接口。
// Repository 接口定义在领域层
public interface OrderRepository {
Order findById(OrderId id);
List<Order> findByCustomerId(CustomerId customerId);
void save(Order order);
void delete(Order order);
}
// 具体实现在基础设施层
@Repository
public class JpaOrderRepository implements OrderRepository {
private final OrderJpaRepository jpaRepository;
private final OrderMapper mapper;
@Override
public Order findById(OrderId id) {
OrderEntity entity = jpaRepository.findById(id.getValue())
.orElseThrow(() -> new OrderNotFoundException(id));
return mapper.toDomain(entity);
}
@Override
public void save(Order order) {
OrderEntity entity = mapper.toEntity(order);
jpaRepository.save(entity);
}
}
// 使用 Repository
@Service
public class OrderService {
private final OrderRepository orderRepository;
public Order createOrder(CreateOrderRequest request) {
Order order = OrderFactory.create(
request.getCustomerId(),
request.getItems()
);
orderRepository.save(order);
return order;
}
}
Factory 模式
Factory 封装了复杂对象的创建逻辑,确保对象创建时处于有效状态。
public class OrderFactory {
public static Order create(CustomerId customerId, List<OrderItemRequest> items) {
// 验证业务规则
if (items.isEmpty()) {
throw new EmptyOrderException("订单不能为空");
}
Order order = Order.create(customerId);
for (OrderItemRequest item : items) {
OrderItem orderItem = OrderItemFactory.create(
item.getProductId(),
item.getQuantity(),
item.getPrice()
);
order.addItem(orderItem);
}
// 触发领域事件
order.registerEvent(new OrderCreatedEvent(order.getId()));
return order;
}
}
public class OrderItemFactory {
public static OrderItem create(ProductId productId, int quantity, Money price) {
if (quantity <= 0) {
throw new InvalidQuantityException("数量必须大于0");
}
if (price.isNegativeOrZero()) {
throw new InvalidPriceException("价格必须大于0");
}
return new OrderItem(productId, quantity, price);
}
}
领域事件
领域事件表示领域中发生的有意义的事情,用于解耦聚合间的通信。
// 领域事件定义
@Value
public class OrderCreatedEvent {
private final OrderId orderId;
private final CustomerId customerId;
private final LocalDateTime occurredAt = LocalDateTime.now();
}
@Value
public class OrderPaidEvent {
private final OrderId orderId;
private final Money amount;
private final LocalDateTime occurredAt = LocalDateTime.now();
}
// 事件发布
@Entity
public class Order {
private List<DomainEvent> domainEvents = new ArrayList<>();
public void pay(Money amount) {
this.status = OrderStatus.PAID;
this.paidAt = LocalDateTime.now();
registerEvent(new OrderPaidEvent(this.id, amount));
}
public List<DomainEvent> getDomainEvents() {
return Collections.unmodifiableList(domainEvents);
}
public void clearEvents() {
domainEvents.clear();
}
}
// 事件处理器
@Component
public class OrderEventHandler {
@EventListener
@Transactional
public void handleOrderCreated(OrderCreatedEvent event) {
// 初始化库存预留
inventoryService.reserve(event.getOrderId());
}
@EventListener
@Transactional
public void handleOrderPaid(OrderPaidEvent event) {
// 确认库存扣减
inventoryService.confirmDeduction(event.getOrderId());
// 发送支付成功通知
notificationService.sendPaymentSuccess(event.getOrderId());
}
}
Specification 模式
Specification 用于封装业务规则,实现规则的组合和复用。
public interface Specification<T> {
boolean isSatisfiedBy(T candidate);
default Specification<T> and(Specification<T> other) {
return candidate -> this.isSatisfiedBy(candidate) && other.isSatisfiedBy(candidate);
}
default Specification<T> or(Specification<T> other) {
return candidate -> this.isSatisfiedBy(candidate) || other.isSatisfiedBy(candidate);
}
}
public class OrderSpecifications {
public static Specification<Order> hasMinimumAmount(Money minimum) {
return order -> order.calculateTotal().isGreaterThanOrEqual(minimum);
}
public static Specification<Order> isPaid() {
return order -> order.getStatus() == OrderStatus.PAID;
}
public static Specification<Order> belongsToCustomer(CustomerId customerId) {
return order -> order.getCustomerId().equals(customerId);
}
}
// 使用
List<Order> orders = orderRepository.findAll(
OrderSpecifications.isPaid()
.and(OrderSpecifications.belongsToCustomer(customerId))
);
DDD 战术设计提供了构建清晰、可维护领域模型的工具集。