一、适配器模式解决什么问题?
一句话:
接口不兼容,但你又不能改原有代码。
现实世界类比:
- 国标插头插不进英标插座
- 需要一个转换头
软件世界中:
- 老系统接口不能改
- 第三方库接口格式不一致
- 新旧系统并存
这时就需要 ------ 适配器(Adapter)。
二、定义
将一个类的接口转换成客户端期望的另一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作。
核心关键词:
- 接口转换
- 不修改原类
- 让旧代码继续工作
三、一个真实业务场景
假设你原本系统中定义了统一支付接口:
python
class Payment:
def pay(self, amount):
pass
后来接入一个第三方支付 SDK:
python
class ThirdPartyPay:
def make_payment(self, money):
print(f"第三方支付 {money}")
问题:
- 你系统里所有代码都调用
pay() - 第三方方法叫
make_payment() - 不能改第三方源码
- 也不想大规模改系统
怎么办?
👉 适配器模式。
四、对象适配器(最常用)
这是 Python 中最常见的方式 ------ 组合实现适配。
python
class PaymentAdapter(Payment):
def __init__(self, third_party_pay):
self.third_party_pay = third_party_pay
def pay(self, amount):
self.third_party_pay.make_payment(amount)
使用:
python
third = ThirdPartyPay()
adapter = PaymentAdapter(third)
adapter.pay(100)
现在:
- 系统依然调用
pay - 实际执行的是
make_payment - 原有代码零改动
这就是对象适配器。
五、类适配器(Python 中不常用)
在某些语言(如 Java)中,可以用多重继承。
Python 也可以,但通常不推荐:
python
class PaymentAdapter(Payment, ThirdPartyPay):
def pay(self, amount):
self.make_payment(amount)
问题:
- 耦合更高
- 不够灵活
- 不利于替换对象
Python 更推荐组合。
六、适配器在真实项目中的应用
适配器模式非常常见,你几乎每天都在用。
1️⃣ 日志系统适配
假设项目统一使用:
python
logger.info("message")
后来接入新日志平台,接口变成:
python
new_logger.log(level="INFO", msg="message")
可以写一个适配器,让新日志符合旧接口。
2️⃣ 数据格式适配
例如:
- 老系统返回 XML
- 新系统使用 JSON
适配器负责转换格式,而不改业务逻辑。
3️⃣ ORM 数据库适配
你可能从 MySQL 切换到 PostgreSQL:
- SQL 语法差异
- 驱动差异
ORM 本质上就是一个巨大适配器。
七、Python 中的"隐式适配"
Python 的动态特性使得很多时候我们不显式写 Adapter 类。
例如:
python
class FileLogger:
def write(self, msg):
print(msg)
class LoggerAdapter:
def __init__(self, obj):
self.obj = obj
def info(self, msg):
self.obj.write(msg)
但更 Pythonic 的方式可能是:
python
obj.info = obj.write
或者直接使用 duck typing。
所以在 Python 中:
很多适配器是"轻量级"的。
八、适配器 vs 装饰器
很多人会混淆。
| 对比点 | 适配器 | 装饰器 |
|---|---|---|
| 目的 | 改变接口 | 增强功能 |
| 是否改变调用方式 | 是 | 否 |
| 是否增加行为 | 不一定 | 是 |
一句话区分:
适配器是"翻译官",
装饰器是"增强器"。
九、什么时候该用适配器?
适合:
- 接入第三方库
- 重构旧系统
- 系统升级接口不兼容
- 做兼容层
不适合:
- 自己新写的代码(直接改接口更简单)
- 没有接口冲突的情况
十、适配器模式的优缺点
✅ 优点
- 不修改原代码
- 提高复用性
- 符合开闭原则
❌ 缺点
- 类数量增加
- 结构复杂度提高
- 过度使用会变成"层层套娃"
十一、一句话总结
适配器模式的本质是"接口转换器"。
它存在的意义不是"优雅",
而是:
在不动旧代码的前提下,让新旧系统兼容。
这在企业级系统中极其常见。