高内聚的洁净门面是协调强耦合子系统的协作协议,统一异常、透传上下文、自动补偿,聚焦“怎么调”而非“做什么”,不掺杂业务逻辑,与@service职责分离。

高内聚的洁净门面(Facade)不是把一堆调用堆在一起,而是让多个强耦合子系统像一个有机整体那样协同工作——内部高度协作,对外只暴露清晰、稳定、可测的契约。
聚焦协作协议,不掺杂业务逻辑
门面的本质是“怎么调”,不是“做什么”。它不计算优惠、不校验库存是否足够、不生成订单号,这些仍由各自的 @Service 层负责。门面只做三件事:
- 把 InventoryNotEnoughException、PaymentTimeoutException 等不同子系统的异常,统一转为带原因码的 OrderOperationFailedException(如 ERR_STOCK_LOCK_TIMEOUT)
- 自动透传 TraceId、TenantId、用户身份上下文,避免 ThreadLocal 泄漏或手动 set/remove
- 在库存预留成功但支付失败时,主动触发异步回滚,而不是把补偿责任推给上层重试逻辑
只在调用失控时引入,不为“有而写”
门面不是标配,而是症状驱动的解药。当出现以下任一情况,说明内部协作已失序,该建 Facade 了:
- 一个 confirmRefund 操作需串行调用库存、优惠、支付、消息四个子系统,且每个调用都重复配置超时、重试、日志和降级策略
- 查券→锁库存→发通知 这条链路,在 Controller、定时任务、MQ 消费器里各自实现一遍
- 准备把 Redis 分布式锁升级为 Consul Lock,但调用点散落在 12 个类中,改一处怕崩一片
封装控制逻辑,拒绝方法转发器
下面这种写法等于没写门面:
真正高内聚的门面必须自带“控制感”:
- 调用前校验参数合法性,并记录结构化入参快照(含来源、版本、签名)
- 为每个子系统设置独立熔断器与超时(比如库存 800ms,支付 2s),而非全局 timeoutMs
- 关键路径打日志:包含各环节耗时、结果码、TraceId、是否触发补偿
- 失败后按预设规则执行轻量协调,例如已扣减库存则立即发起回补任务,而非抛异常等上游处理
与 @Service 明确分工,共存不混淆
@Service 表达“领域行为”,比如 order.cancel()、user.applyVip(),它关注状态变更与业务规则;Facade 表达“协作协议”,比如 OrderCollaborationFacade.confirmRefund(),它只保证顺序、收敛错误、保持上下文一致。两者职责不重叠,也不互相替代。
不复杂但容易忽略:门面的价值不在“加了一层”,而在“收住了混乱”。











