外观模式
外观模式用于给复杂子系统提供一个简单统一的入口。
一句话理解:内部很复杂,外部只暴露一个好用的门面。
解决什么问题
一个业务流程可能需要调用多个子系统:
text
创建订单
-> 校验库存
-> 锁定库存
-> 计算价格
-> 创建支付单
-> 发送消息如果调用方直接编排所有步骤,会导致:
- 调用方知道太多细节。
- 流程代码散落在多个地方。
- 子系统变化会影响调用方。
外观模式把复杂流程封装到一个高层接口中。
基本结构
text
Client -> Facade -> SubsystemA
-> SubsystemB
-> SubsystemC角色:
Facade:统一入口。Subsystem:具体子系统。Client:只调用外观,不直接编排复杂子系统。
Java 示例
子系统:
java
class InventoryService {
void lockStock(long skuId, int count) {
System.out.println("lock stock");
}
}
class PriceService {
int calculate(long skuId, int count) {
return 100 * count;
}
}
class PaymentService {
void createPayment(long orderId, int amount) {
System.out.println("create payment");
}
}外观:
java
class OrderFacade {
private final InventoryService inventoryService;
private final PriceService priceService;
private final PaymentService paymentService;
OrderFacade(InventoryService inventoryService,
PriceService priceService,
PaymentService paymentService) {
this.inventoryService = inventoryService;
this.priceService = priceService;
this.paymentService = paymentService;
}
public void createOrder(long orderId, long skuId, int count) {
inventoryService.lockStock(skuId, count);
int amount = priceService.calculate(skuId, count);
paymentService.createPayment(orderId, amount);
}
}调用方:
java
orderFacade.createOrder(1001L, 2001L, 2);调用方不需要知道下单背后调用了几个服务。
使用场景
- 对外提供简单 API。
- 封装复杂业务流程。
- 防止调用方直接依赖多个子系统。
- 分层架构中 Controller 调用应用服务。
- 对第三方 SDK 做统一封装。
优点
- 降低调用方复杂度。
- 减少外部对子系统的直接依赖。
- 统一流程入口,方便加日志、事务、权限。
- 子系统变化时影响范围更小。
缺点
- 外观类容易变成大而全的上帝类。
- 如果外观层只是简单转发,价值不大。
- 过度封装可能隐藏必要细节。
和适配器模式的区别
| 模式 | 重点 |
|---|---|
| 外观 | 简化复杂子系统调用 |
| 适配器 | 转换不兼容接口 |
外观是为了“更好用”,适配器是为了“能兼容”。
实战注意
在 Java Web 项目中,很多 ApplicationService 或 FacadeService 实际上就是外观模式。它们应该负责流程编排,不应该塞满底层技术细节。