在领域驱动设计中,如何利用领域服务来解决复杂业务逻辑中跨多个聚合的用例问题?请给出实际的应用场景与代码示例。

在领域驱动设计(Domain-Driven Design, DDD)中,领域服务是一种重要的领域模型组件,用于封装领域逻辑,特别是当该逻辑涉及多个聚合(Aggregate)时。领域服务不持有状态,而是作为协调不同聚合的方法集合。以下是一个具体的应用场景和代码示例,用以展示如何利用领域服务解决跨多个聚合的用例问题。

应用场景

假设我们正在开发一个电子商务平台,主要关注订单管理和库存管理两个核心领域。在这个系统中,当用户提交订单时,我们需要确保有足够的库存来满足订单需求。如果库存充足,则减少相应商品的库存,并创建订单;如果没有足够的库存,则需要通知用户。这个过程涉及到Order聚合和Inventory聚合,两个聚合之间存在复杂的业务逻辑。

代码示例

1. 定义聚合

首先是Order聚合和Inventory聚合的定义:

public class Order {
    private OrderId id;
    private List<OrderLine> lines;

    public OrderId getId() {
        return id;
    }

    public void addLine(OrderLine line) {
        this.lines.add(line);
    }
}

public class Inventory {
    private InventoryId id;
    private Map<ProductId, Integer> stockLevels;

    public boolean hasStockFor(ProductId productId, int quantity) {
        return stockLevels.getOrDefault(productId, 0) >= quantity;
    }

    public void reduceStock(ProductId productId, int quantity) {
        int newQuantity = stockLevels.get(productId) - quantity;
        stockLevels.put(productId, newQuantity);
    }
}

2. 创建领域服务

接下来,创建一个领域服务OrderService,用于协调订单创建和库存检查:

public class OrderService {

    private InventoryRepository inventoryRepository;
    private OrderRepository orderRepository;

    public OrderService(InventoryRepository inventoryRepository, OrderRepository orderRepository) {
        this.inventoryRepository = inventoryRepository;
        this.orderRepository = orderRepository;
    }

    public void placeOrder(OrderId orderId, List<OrderLine> orderLines) {
        // 检查库存
        for (OrderLine line : orderLines) {
            Inventory inventory = inventoryRepository.findByProductId(line.getProductId());
            if (!inventory.hasStockFor(line.getProductId(), line.getQuantity())) {
                throw new InsufficientStockException("Insufficient stock for product: " + line.getProductId());
            }
        }

        // 创建订单
        Order order = new Order();
        order.setId(orderId);
        for (OrderLine line : orderLines) {
            order.addLine(line);
        }
        orderRepository.save(order);

        // 减少库存
        for (OrderLine line : orderLines) {
            Inventory inventory = inventoryRepository.findByProductId(line.getProductId());
            inventory.reduceStock(line.getProductId(), line.getQuantity());
            inventoryRepository.save(inventory);
        }
    }
}

总结

通过使用领域服务OrderService,我们可以将跨多个聚合的业务逻辑集中在一个地方进行处理,从而提高代码的可维护性和可测试性。领域服务充当了不同聚合之间的协调者,确保了业务规则的一致性和正确性。