对象越来越多时,代码总会在某个时刻变成一团乱麻。当一个页面中的视图控制器、网络、缓存和日志记录器开始互相直接调用时,改好一处往往又会弄坏另一处。
这时通常会考虑 Mediator、Observer 和 Facade。三者都被介绍为“整理对象通信”的方式,但它们实际解决的问题并不相同。
Mediator 将纠缠的关系集中控制,Observer 通过一对多通知处理状态变化,Facade 则用简单入口隐藏复杂内部实现。
记住这一句话,你就完成一半了。下面我们结合代码说明各自的使用时机和差异。
先用一句话总结三种模式
先把核心内容整理出来,方便混淆时回看。
- Mediator — 多个对象不直接互相引用,而是通过一个中介者进行通信
- Observer — 一个对象的状态发生变化时,自动通知多个订阅它的对象
- Facade — 在复杂子系统前提供一个简单接口,将其隐藏起来
虽然三者都在整理“通信”,但侧重点不同。
Mediator 减少关系复杂度,Observer 处理变化传播,Facade 降低使用复杂度。
Mediator vs Observer,有什么区别?
这两个最容易混淆,因为它们都能避免对象之间直接调用。
区别在于关系的方向。
Observer 的方向很明确。一个 Subject 发生变化后,更新会沿一个方向流向订阅者。比如聊天室收到新消息时,页面、通知徽章和声音各自做出响应。
Mediator 的方向则彼此交织。点击按钮会激活文本框,而文本框又会改变保存按钮的状态,如此循环。这种多对多关系由中介者代为协调。
// Observer:状态变化沿一个方向传播
protocol Observer: AnyObject { func update(_ count: Int) }
final class Cart {
private var observers: [Observer] = []
var items = 0 { didSet { observers.forEach { $0.update(items) } } }
func subscribe(_ o: Observer) { observers.append(o) }
}
final class Badge: Observer {
func update(_ count: Int) { print("购物车徽章: \(count)") }
}
let cart = Cart()
cart.subscribe(Badge())
cart.items = 3
// 输出:购物车徽章: 3
购物车发生变化后,徽章会自动跟着更新。Cart 不需要知道 Badge 是什么。
而 Mediator 会由中介者持有对象之间的规则。
// Mediator:由中介者管理纠缠的规则
final class FormMediator {
var isAgreed = false
func agreedChanged(_ value: Bool, submit: Button) {
isAgreed = value
submit.isEnabled = value // 规则:同意后启用提交
}
}
final class Button { var isEnabled = false }
let submit = Button()
let mediator = FormMediator()
mediator.agreedChanged(true, submit: submit)
print(submit.isEnabled)
// 输出: true
复选框和按钮不需要直接了解彼此,中介者会代为执行“同意后启用提交”的规则。
Facade 的侧重点略有不同
Facade 与前两者的目的本身就不同。它不是协调通信,而是将复杂内部封装起来使其不可见的模式。
假设完成一笔订单需要依次调用支付、库存、配送和通知模块。调用方的代码很快就会变得混乱。
Facade 会将这些统一到一个入口之后。
final class OrderFacade {
func placeOrder(_ id: String) {
Payment().charge(id)
Stock().reduce(id)
Delivery().book(id)
print("完成订单: \(id)")
}
}
OrderFacade().placeOrder("A-1024")
// 输出:订单完成: A-1024
从外部只需调用一次placeOrder即可。内部有多少模块都不必关心。
关键就在这里。Facade 不是让对象彼此通信,而是简化调用方与复杂系统之间的关系。方向朝向内部。
一眼对比
下面整理了我在 2026 年实际工作中的分类方式。
| 分类 | Mediator | Observer | Facade |
|---|---|---|---|
| 解决的问题 | 纠缠的多对多关系 | 状态变化传播 | 隐藏复杂内部实现 |
| 关系方向 | 相互交织(中心协调) | 一对多(单向) | 调用方→系统 |
| 耦合度变化 | 降低对象之间的耦合 | 分离主体与订阅者 | 降低使用复杂度 |
| 典型示例 | 表单校验、聊天室协调 | 通知、数据绑定 | 支付与订单统一 API |
通过表格可以明显看出,三者并不重叠。
何时使用,何时避免
模式被滥用后反而会带来问题。如果把所有纠缠的关系都交给 Mediator,中介者很容易变成 God object。
- Mediator — 当 3~4 个或更多对象彼此直接引用,且规则相互纠缠时使用。如果规则很简单,就应避免使用,否则中介者会变得过于庞大。
- Observer — 当多个位置都需要知道某一处的变化时使用。不要忘记取消订阅,否则可能造成内存泄漏。
- Facade — 当你想隐藏复杂的调用流程时使用。在必须精细控制内部实现的地方,它反而会造成阻碍。
一句话总结:关系纠缠用 Mediator,需要通知变化用 Observer,想隐藏流程用 Facade。
面试时可以这样回答
问:Mediator 和 Observer 有什么区别?
Observer 是一对多结构,Subject 的状态变化会沿一个方向传播给订阅者。Mediator 是多对多结构,由中介者在中心协调相互纠缠的对象之间的交互规则。方向性和关系复杂度是两者的核心区别。
问:Facade 也能降低耦合度,它和 Mediator 有什么区别?
Facade 在子系统前提供一个简单接口,降低调用方与系统之间的使用复杂度。而 Mediator 的目的是协调同级对象之间的相互通信。可以回答:“Facade 是单向简化,Mediator 是交互协调。”
与其死记三种模式,不如先问自己当前的代码属于“关系纠缠问题”“变化传播问题”,还是“流程复杂问题”。确定答案后,模式自然会随之而来。今天的重构就选一个试着应用吧。

