一. 引言
今天我们从一个最常见的场景来切入,讲解外观模式。现在中午订外卖已经成了非常普遍的现象。我们打开 App,点了一份麻辣香锅,然后30分钟后门铃响,外卖送到了------看似平常,但这背后发生了什么?
实际上,当我们点击"下单"的那一刻,系统可能在悄悄调用:
- 餐厅接口,确认菜品与库存
- 支付网关,处理付款
- 配送系统,派送骑手
- 物流追踪服务,实时更新订单状态
如果把这些功能都直接暴露给客户端,每次下单都要手动调用一大堆接口,代码会变得异常复杂。
这就是外观模式(Facade Pattern)登场的场景:它为复杂系统提供一个统一接口,让客户端只需关注核心流程。
二. 外观模式简介
我们可以把外观模式理解为:为复杂子系统提供一个统一的高层接口,让系统使用者能够更简单地完成操作,而无需了解内部复杂细节。
在外卖的例子里:
- 客户端:用户(下单的人)
- 外观(Facade):FoodDeliveryFacade
- 子系统(Subsystem):餐厅、支付、配送

核心思想是:客户端只和外观接口交互,外观负责调度各个子系统完成完整流程。
三. 代码示意:用 Swift 模拟外卖系统
接下来,我们通过 Swift 代码来展示如何用外观模式封装外卖系统的流程。
3.1 子系统定义
每个子系统负责自己的职责:
餐厅系统:
Swift
// 餐厅系统:处理点餐和做菜
struct RestaurantSystem {
func selectDish(_ name: String) {
print("选择菜品:\(name)")
}
func prepareDish() {
print("厨房正在准备菜品...")
}
}
支付系统:
Swift
// 支付系统:模拟付款
struct PaymentSystem {
func pay(amount: Double) {
print("支付金额:¥\(amount)")
}
}
配送系统:
Swift
// 配送系统:负责骑手和派送
struct DeliverySystem {
func assignRider() {
print("派送员已接单")
}
func deliver() {
print("配送中...")
}
}
每个子系统内部可以很复杂,但对客户端来说,这些细节都并不需要关心。
3.2 外观类(Facade)
外观类统一封装整个下单流程,让客户端只需调用一个方法即可完成整个订单操作:
Swift
// 外观类:统一封装整个下单流程
struct FoodDeliveryFacade {
private let restaurant = RestaurantSystem()
private let payment = PaymentSystem()
private let delivery = DeliverySystem()
func placeOrder(dish: String, amount: Double) {
restaurant.selectDish(dish)
restaurant.prepareDish()
payment.pay(amount: amount)
delivery.assignRider()
delivery.deliver()
print("订单已完成,祝您用餐愉快!")
}
}
3.3 客户端调用示意
Swift
let app = FoodDeliveryFacade()
app.placeOrder(dish: "麻辣香锅", amount: 48.0)
输出示意:
Swift
选择菜品:麻辣香锅
厨房正在准备菜品...
支付金额:¥48.0
派送员已接单
配送中...
订单已完成,祝您用餐愉快!
客户端只需一句 placeOrder(),无需了解子系统内部的调用顺序和复杂流程,这就是外观模式的核心价值。
四. 模式分析
从前面的代码示意可以看出,外观模式在外卖系统里起到了"中介"和"封装"的作用:
- 客户端:只需要调用 placeOrder(),无需关心内部流程
- 外观(Facade):FoodDeliveryFacade 统一管理各个子系统的调用顺序
- 子系统(Subsystem):餐厅、支付、配送,各自负责具体逻辑
角色 | Swift 实现 | 说明 |
---|---|---|
Facade(外观) | FoodDeliveryFacade | 对外提供统一接口,隐藏内部子系统的复杂调用 |
Subsystem(子系统) | RestaurantSystem、PaymentSystem、DeliverySystem | 各自独立实现具体功能,外部无需知道内部流程 |
Client(客户端) | 调用 placeOrder() 的应用层 | 只与外观交互,降低耦合,简化调用 |
其实在实际开发中,我们在很多场景化中都会使用到这个外观模式。
直播间/播放器:
- 比如一个直播 SDK,内部涉及视频拉流、音频处理、弹幕显示、网络状态监控等多个模块
- 客户端只需调用 startLive() 或 play(url:),即可完成整个播放流程
多媒体编辑系统:
- 视频编辑 App 可能涉及视频轨道、音频轨道、滤镜、转场等子系统
- 外观类可以封装成 VideoEditorFacade,客户端调用 exportVideo() 就能完成整个流程
核心思想永远是一样的:外观模式让客户端只关注核心操作,无需了解内部复杂实现。
不管是下单外卖、播放视频,还是开启直播间,调用方式都是统一、简单、直观的。
五. 优缺点总结
5.1 优点
降低客户端复杂性:
外观模式可以降低客户端的复杂性,当外部需要使用某些复杂功能时,只需要调用外观提供的统一接口,而不比知道内部子系统如何写作。
降低耦合:
客户端与子系统功能解耦,系统可以独立修改或升级,而不影响外部调用。
统一管理流程:
外观类可以统一管理子系统调用顺序、错误处理等逻辑,让流程清晰可控。
5.2 缺点
如果封装过多功能,外观类会变得过大,维护难度增加。客户端只能按照外观提供的接口调用,某些自定义需求可能受限。
六. 结语
外观模式的核心价值在于 "让复杂系统对外变得简单"。
不管是中午点一份麻辣香锅、播放一段视频,还是开启一个直播间,客户端看到的都是一个清晰、统一的接口:
Swift
placeOrder()
play(url:)
startLive()
内部如何调用多个子系统、处理复杂逻辑,这些细节被外观隐藏起来,但一切依然井然有序。