Service Facade 在项目分层中应该怎么设计?
简化版
Service Facade 通常放在 Controller 和多个业务服务之间,对外提供粗粒度用例接口,对内协调领域服务、基础服务和外部系统。设计时要让 Facade 负责流程编排和边界收口,不要把所有领域规则都堆进 Facade。
详细版
典型分层:
Controller
-> Facade / Application Service
-> Domain Service
-> Repository
-> External Client
Facade 适合承担:
- 用例入口;
- 参数转换;
- 权限校验入口;
- 事务边界;
- 多服务编排;
- 结果聚合;
- 异常转换。
不适合承担:
- 大量领域规则;
- 底层数据访问细节;
- 所有业务逻辑堆积;
- 跨多个边界的万能协调。
好的 Facade 应该让上层调用简单,让下层职责清楚。
完整版教学
一、Facade 在分层架构中的位置
很多 Java Web 项目会有:
Controller -> Service -> Mapper
当业务复杂后,一个 Controller 可能要调用很多 Service。
这时可以增加 Facade 或 Application Service:
Controller -> OrderFacade -> UserService
-> StockService
-> OrderService
-> MessageClient
Controller 只关心一个用例入口。
二、Facade 应该表达用例
Facade 的方法最好是业务用例级别:
createOrder()
cancelOrder()
queryOrderDetail()
submitApproval()
generateReport()
不要把 Facade 写成纯工具集合:
doSomething()
handle()
process()
方法名越贴近业务用例,边界越清楚。
三、Facade 负责流程,领域服务负责规则
Facade 可以组织流程:
userService.check();
stockService.lock();
orderService.create();
eventPublisher.publish();
但“订单能不能取消”“库存怎么扣”“价格怎么算”这类领域规则,最好放在对应领域服务或领域对象里。
否则 Facade 会越来越胖。
四、事务边界可以放在 Facade
如果一个用例涉及多个本地数据库操作,事务边界常放在 Facade 或应用服务层。
@Transactional
public OrderResult createOrder(CreateOrderCommand command) {
// 编排多个服务
}
这样一个完整用例在同一个事务里执行。
但如果涉及远程服务,不能简单依赖本地事务,要考虑最终一致性、补偿、消息可靠性等问题。
五、Facade 和 Domain Service 的区别
Facade 更偏用例编排,Domain Service 更偏领域规则。
例如:
OrderFacade:创建订单流程
PriceService:计算价格规则
StockService:库存锁定规则
Facade 可以调用这些服务,但不要替代它们。
六、常见误区与追问
Service Facade 应围绕应用用例,而不是简单映射数据库表。一次转账用例含校验、记账、事件3步,事务边界可由 Facade 组织,但余额不可为负等规则应由领域对象保证。这样 Controller 只处理协议,Facade 处理流程,领域层处理不变量。
| 检查维度 | 判定依据 |
|---|---|
| Service Facade | 用例编排、事务、权限边界 |
| Domain Service | 跨实体业务规则与不变量 |
记忆钩子:Facade 决定“这次用例走哪些步骤”,领域层决定“每一步什么才合法”。
- 误区:每张表都应有一个 Facade。 外观按业务用例和子系统边界设计,不按持久化表机械映射。
- 追问:Controller 能直接调用 Domain Service 吗? 简单查询可以权衡,但复杂用例应经应用层保持事务和编排一致。
- 误区:事务越大越安全。 跨远程调用的长事务会增加锁持有和失败复杂度。
- 追问:Facade 可以返回领域实体吗? 对外边界通常返回 DTO,避免实体被越层修改和序列化泄漏。
- 追问:如何避免贫血模型? 把业务不变量和状态变化放回实体或值对象,Facade 只协调它们。
七、加强记忆
Service Facade 是项目里的“用例入口层”:对上简化 Controller,对下编排多个服务。它适合放流程、事务、聚合和异常转换,不适合堆满领域规则。边界清楚,Facade 才不会变成上帝类。