#洋葱架构
#洋葱架构的本质
Jeffrey Palermo 在 2008 年提出了洋葱架构,核心理念和六边形架构一脉相承:让核心业务逻辑位于系统中心,外部依赖只能依赖内层。
洋葱架构:
┌────────────────────────────────────┐
│ Application Services │
│ ┌──────────────────────────┐ │
│ │ Domain Services │ │
│ │ ┌────────────────┐ │ │
│ │ │ Domain │ │ │
│ │ │ Entities │ │ │
│ │ │ Repositories │ │ │
│ │ │ (Ports) │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────────┘ │
└────────────────────────────────────┘
核心:Entities + Repository Interfaces (Ports)
外层:Application Services、Infrastructure
依赖方向:全部指向核心#二、核心层次详解🔴
#2.1 最内层:Domain(核心)
// 实体:业务规则
class Order {
private OrderId id;
private Money totalAmount;
public void pay(Money amount) {
if (amount.compareTo(totalAmount) < 0) {
throw new InsufficientBalanceException();
}
this.status = OrderStatus.PAID;
}
}
// 仓储端口(接口)
interface OrderRepository {
void save(Order order);
Optional<Order> findById(OrderId id);
}#2.2 第二层:Domain Services
// 领域服务:跨实体的业务逻辑
class OrderDomainService {
public Money calculateDiscount(Order order, Coupon coupon) {
return coupon.calculateDiscount(order.getTotalAmount());
}
}#2.3 第三层:Application Services
// 应用服务:编排用例
class CreateOrderService {
private final OrderRepository orderRepository;
private final PaymentGateway paymentGateway;
public Order execute(CreateOrderCommand cmd) {
Order order = new Order(cmd.getUserId(), cmd.getItems());
orderRepository.save(order);
paymentGateway.initiate(order);
return order;
}
}#2.4 最外层:Infrastructure
// 基础设施:实现端口
class JpaOrderRepository implements OrderRepository {
@Override
public void save(Order order) {
jpaTemplate.save(order);
}
}#三、洋葱架构 vs 六边形架构
| 维度 | 洋葱架构 | 六边形架构 |
|---|---|---|
| 核心 | Domain Entities + Repository Ports | Application Core + Ports |
| 命名 | 层次清晰(从内到外) | 形状直观(六边形) |
| 依赖注入 | 构造函数注入 | 构造函数注入 |
| 适用场景 | 复杂业务域 | 需要清晰边界的系统 |
本质上,两者是一样的思想:核心不依赖外部,外部依赖核心。
#四、面试总结
| 级别 | 期望回答 |
|---|---|
| P5 | 能说出洋葱架构的层次结构 |
| P6 | 能对比六边形和洋葱架构 |
| P7 | 有实际落地经验 |