在复杂系统中,一个功能往往需要调用多个子系统:
- 数据库
- 缓存
- 消息队列
- 日志系统
- 权限系统
如果客户端直接调用这些子系统,就会出现:
- 调用顺序复杂
- 强耦合
- 代码难维护
这时就需要一个 统一入口。
这就是 外观模式(Facade)。
一、外观模式解决什么问题?
一句话:
为复杂子系统提供一个统一的简化接口。
关键词:
- 简化接口
- 隐藏复杂性
- 解耦客户端与子系统
二、一个真实业务场景
假设我们有一个电商"下单流程"。
一个订单涉及:
1️⃣ 库存系统
2️⃣ 支付系统
3️⃣ 物流系统
4️⃣ 通知系统
如果客户端自己调用:
python
inventory.check(product_id)
payment.pay(user_id, amount)
logistics.create_order(order)
notification.send(user)
问题:
- 调用顺序必须正确
- 逻辑散落在各处
- 修改流程很困难
这就是典型的复杂子系统问题。
三、外观模式的核心思想
引入一个 Facade(外观类)。
客户端只调用它:
python
order_service.create_order(...)
内部再协调各个子系统。
结构:
Client
↓
Facade
↓ ↓ ↓
子系统A
子系统B
子系统C
四、Python 实现外观模式
我们用"订单系统"做例子。
1️⃣ 子系统
库存系统:
python
class InventorySystem:
def check_stock(self, product_id):
print("检查库存")
return True
支付系统:
python
class PaymentSystem:
def pay(self, user_id, amount):
print("支付成功")
物流系统:
python
class LogisticsSystem:
def create_shipment(self, order_id):
print("创建物流订单")
通知系统:
python
class NotificationSystem:
def notify(self, user_id):
print("发送订单通知")
2️⃣ 外观类(Facade)
python
class OrderFacade:
def __init__(self):
self.inventory = InventorySystem()
self.payment = PaymentSystem()
self.logistics = LogisticsSystem()
self.notification = NotificationSystem()
def place_order(self, user_id, product_id, amount):
if not self.inventory.check_stock(product_id):
print("库存不足")
return
self.payment.pay(user_id, amount)
self.logistics.create_shipment(product_id)
self.notification.notify(user_id)
print("订单完成")
3️⃣ 客户端使用
客户端代码:
python
order_service = OrderFacade()
order_service.place_order(1001, 2001, 300)
客户端完全不需要知道:
- 库存系统
- 支付系统
- 物流系统
- 通知系统
这就是外观模式的核心价值。
五、外观模式的本质
外观模式其实就是:
封装复杂流程,提供简单接口。
它解决的不是结构问题,而是:
- 系统复杂度问题
六、外观模式 vs 适配器模式
很多人会混淆。
区别非常关键:
| 模式 | 作用 |
|---|---|
| 适配器 | 转换接口 |
| 外观 | 简化接口 |
例子:
适配器:
旧接口 → 新接口
外观:
复杂系统 → 简单入口
一句话总结:
适配器解决"接口不兼容",
外观解决"系统太复杂"。
七、外观模式在真实项目中的应用
非常非常常见。
1️⃣ Service 层
典型三层架构:
Controller
↓
Service(Facade)
↓
DAO / Repository
Service 层就是外观模式。
2️⃣ SDK 封装
例如云 SDK:
用户只调用:
upload_file()
内部却调用:
- 认证
- 分片
- 上传
- 校验
3️⃣ 微服务网关
API Gateway:
Client
↓
Gateway(Facade)
↓
多个微服务
八、外观模式优缺点
✅ 优点
1 简化客户端代码
客户端只调用一个接口。
2 降低耦合
客户端不依赖子系统。
3 提高系统可维护性
内部系统可以自由修改。
❌ 缺点
1 外观类可能变成"上帝类"
如果不断添加逻辑。
2 可能隐藏过多细节
高级用户可能需要直接访问子系统。
九、外观模式设计建议
在大型系统中:
建议 Facade + 子系统并存。
普通用户:
使用 Facade
高级用户:
直接调用子系统
这样既简单又灵活。
十、一句话总结
外观模式的本质是:
为复杂系统提供一个简单入口。
它的核心价值不是"结构设计",而是:
降低系统复杂度。
结构型模式还剩下两个:
1️⃣ 享元模式(Flyweight) ------ 解决内存问题
2️⃣ 代理模式(Proxy) ------ 控制访问