← 返回首页
🎯

DDD战略设计

📂 architecture ⏱ 2 min 258 words

DDD战略设计

上下文映射模式

上下文映射描述了限界上下文之间的关系和集成方式。

常见的上下文映射关系:

1. 共享内核(Shared Kernel)
   ┌─────────┐     ┌─────────┐
   │ 上下文A  │◄───►│ 上下文B  │
   └─────────┘     └─────────┘
        │               │
        └───────┬───────┘
                ▼
        共享的领域模型

2. 客户-供应商(Customer-Supplier)
   ┌─────────┐     ┌─────────┐
   │  供应商  │────►│  客户   │
   └─────────┘     └─────────┘

3. 防腐层(Anti-Corruption Layer)
   ┌─────────┐     ┌─────────┐
   │ 上下文A  │────►│ ACL │───►│ 上下文B  │
   └─────────┘     └─────────┘

4. 开放主机服务(Open Host Service)
   ┌─────────┐
   │ 上下文A  │
   └────┬────┘
        │
        ▼
   ┌─────────────┐
   │  公开API    │
   └────┬────┬───┘
        │    │
        ▼    ▼
   ┌────┴┐ ┌┴────┐
   │客户1 │ │客户2 │
   └─────┘ └─────┘

防腐层实现

防腐层(ACL)用于隔离外部模型,保护领域模型的纯洁性。

// 防腐层:将外部用户模型转换为内部领域模型
@Component
public class UserAntiCorruptionLayer {
    
    private final ExternalUserService externalUserService;
    
    public Customer toCustomer(ExternalUserId externalId) {
        // 调用外部服务
        ExternalUser externalUser = externalUserService.getUser(externalId.getValue());
        
        // 转换为内部领域模型
        return Customer.builder()
            .id(new CustomerId(externalUser.getId()))
            .name(new UserName(externalUser.getFirstName(), externalUser.getLastName()))
            .email(new Email(externalUser.getEmailAddress()))
            .phone(new Phone(externalUser.getMobileNumber()))
            .build();
    }
    
    public ExternalUserId toExternalId(CustomerId customerId) {
        return new ExternalUserId(customerId.getValue());
    }
}

// 使用防腐层
@Service
public class OrderService {
    
    private final UserAntiCorruptionLayer userACL;
    private final OrderRepository orderRepository;
    
    public Order createOrder(CustomerId customerId, List<OrderItemRequest> items) {
        // 通过 ACL 获取客户信息,不直接依赖外部模型
        Customer customer = userACL.toCustomer(customerId);
        
        Order order = OrderFactory.create(customer.getId(), items);
        orderRepository.save(order);
        
        return order;
    }
}

上下文映射实现

// 共享内核:多个上下文共享的部分领域模型
@SharedKernel
public class ProductId {
    private final String value;
}

// 客户-供应商关系实现
// 供应商(订单上下文)提供接口
@RestController
@RequestMapping("/api/orders")
public class OrderSupplierController {
    
    @GetMapping("/{orderId}/summary")
    public OrderSummary getOrderSummary(@PathVariable String orderId) {
        Order order = orderService.findById(new OrderId(orderId));
        return new OrderSummary(
            order.getId().getValue(),
            order.getStatus().name(),
            order.calculateTotal()
        );
    }
}

// 客户(支付上下文)使用防腐层调用
@Component
public class OrderAntiCorruptionLayer {
    
    private final RestTemplate restTemplate;
    
    public OrderInfo getOrderInfo(String orderId) {
        OrderSummary summary = restTemplate.getForObject(
            "http://order-service/api/orders/" + orderId + "/summary",
            OrderSummary.class
        );
        
        // 转换为支付上下文的模型
        return new OrderInfo(
            new OrderId(summary.getOrderId()),
            Money.of(summary.getTotal()),
            OrderStatus.valueOf(summary.getStatus())
        );
    }
}

上下文关系决策

选择上下文映射模式需要考虑:

战略设计的目标是管理限界上下文之间的复杂性,保持每个上下文的内聚性。