外观模式是为内部强耦合子系统设计的可控协作入口,聚焦错误聚合、上下文透传与轻量协调,非业务逻辑容器,仅在调用失控时引入,须封装控制逻辑而非简单转发。

外观模式不是给微服务“加一层壳”,而是为内部多个强耦合子系统(如库存、优惠、支付、消息)设计一个可控、可测、可演进的协作入口。它不面向外部请求,也不替代 API 网关;它的价值在于收口“怎么调”,而非定义“做什么”。
明确 Facade 的职责边界
Facade 是跨子系统的编排器,不是业务逻辑容器。它不实现优惠计算、不持有订单状态、不管理事务语义——这些仍归对应子系统或 @Service 层负责。Facade 只聚焦三件事:
- 错误聚合:把 InventoryNotEnoughException、InvalidSignatureException 等统一转为带原因码的 OrderCreationFailedException(如 ERR_INVENTORY_SHORTAGE)
- 上下文透传:自动注入 TraceId、TenantId,并隔离 ThreadLocal 中的用户身份,避免下游污染
- 轻量协调:库存扣减失败时,主动触发已预留库存的回滚,而不是把补偿甩给上层重试逻辑
只在真正需要时引入 Facade
当你的微服务出现以下情况之一,说明内部调用已开始失控,Facade 就不再是可选项:
- 一个业务操作(如 confirmRefund)需串行调用 4 个以上子系统,且每步都手动配置超时、重试、日志和降级策略
- 相同调用链(比如先查券再锁库存再发通知)在 Controller、定时任务、MQ 消费器中重复出现 3 次以上
- 某个子系统即将替换(如 Redis 分布式锁升级为 Consul Lock),但调用点散落在 10+ 个类里,改不动也不敢动
避免写成“方法转发器”
只做简单委托的 Facade 类等于没写。例如下面这种写法没有实际价值:
public void createOrder(OrderRequest req) { inventory.decrease(req); payment.charge(req); message.sendSuccess(req); }真正有效的 Facade 必须封装控制逻辑:
- 调用前校验参数合法性,并统一记录入参快照
- 对每个子系统调用设置独立超时与熔断策略(非全局 timeoutMs)
- 异常发生后,按预设规则执行补偿动作(如已扣库存需异步回补)
- 关键路径打结构化日志,包含各子系统耗时、结果码、TraceId
与 @Service 的分工要清晰
@Service 表达的是“领域行为”,比如 order.cancel()、user.applyVip(),它关注状态变更和业务规则。Facade 则是“协作协议”,比如 OrderCollaborationFacade.confirmRefund(),它只保证调用顺序、错误收敛与上下文一致性。两者共存不冲突,但不能混用:不要在 Facade 里写满 if-else 优惠分支,也不要让 @Service 直接 new 多个客户端并手动编排。











