Python 桥接模式
桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。简单来说,就是把事物的多种变化维度拆分开,让每个维度都能独立扩展。
生活中的桥接模式比喻
想象一下遥控器和电视的关系:
- 遥控器(抽象部分):提供控制接口(开关、音量、频道)
- 电视(实现部分):具体执行操作(索尼电视、三星电视、小米电视)
遥控器不需要知道具体是哪种电视,电视也不需要知道是哪种遥控器,它们通过一个"桥梁"连接,各自可以独立升级换代。
为什么需要桥接模式?
传统方式的局限性
假设我们要设计一个图形绘制系统,支持不同形状和颜色:
实例
# 传统实现 - 类爆炸问题
class RedCircle:
def draw(self):
print("绘制红色圆形")
class BlueCircle:
def draw(self):
print("绘制蓝色圆形")
class RedRectangle:
def draw(self):
print("绘制红色矩形")
class BlueRectangle:
def draw(self):
print("绘制蓝色矩形")
# 每增加一种颜色或形状,都需要创建新的类
# 3种颜色 × 3种形状 = 9个类!
class RedCircle:
def draw(self):
print("绘制红色圆形")
class BlueCircle:
def draw(self):
print("绘制蓝色圆形")
class RedRectangle:
def draw(self):
print("绘制红色矩形")
class BlueRectangle:
def draw(self):
print("绘制蓝色矩形")
# 每增加一种颜色或形状,都需要创建新的类
# 3种颜色 × 3种形状 = 9个类!
桥接模式的优势
实例
# 桥接模式实现
class Color:
"""颜色接口 - 实现部分"""
def apply_color(self):
pass
class Shape:
"""形状抽象 - 抽象部分"""
def __init__(self, color):
self.color = color # 桥接的关键!
def draw(self):
pass
# 只需要:3种颜色 + 3种形状 = 6个类
# 而不是:3 × 3 = 9个类
class Color:
"""颜色接口 - 实现部分"""
def apply_color(self):
pass
class Shape:
"""形状抽象 - 抽象部分"""
def __init__(self, color):
self.color = color # 桥接的关键!
def draw(self):
pass
# 只需要:3种颜色 + 3种形状 = 6个类
# 而不是:3 × 3 = 9个类
桥接模式的核心结构
让我们通过一个完整的示例来理解桥接模式的组件:

四个关键角色
- 抽象部分(Abstraction):定义抽象接口,维护对实现部分的引用
- 具体抽象(RefinedAbstraction):扩展抽象接口
- 实现部分(Implementor):定义实现接口
- 具体实现(ConcreteImplementor):具体实现接口
完整代码示例:图形绘制系统
步骤 1:定义实现部分接口(颜色)
实例
from abc import ABC, abstractmethod
class Color(ABC):
"""颜色接口 - 实现部分"""
@abstractmethod
def apply_color(self):
pass
class Red(Color):
"""具体实现 - 红色"""
def apply_color(self):
return "红色"
class Blue(Color):
"""具体实现 - 蓝色"""
def apply_color(self):
return "蓝色"
class Green(Color):
"""具体实现 - 绿色"""
def apply_color(self):
return "绿色"
class Color(ABC):
"""颜色接口 - 实现部分"""
@abstractmethod
def apply_color(self):
pass
class Red(Color):
"""具体实现 - 红色"""
def apply_color(self):
return "红色"
class Blue(Color):
"""具体实现 - 蓝色"""
def apply_color(self):
return "蓝色"
class Green(Color):
"""具体实现 - 绿色"""
def apply_color(self):
return "绿色"
步骤 2:定义抽象部分(形状)
实例
class Shape(ABC):
"""形状抽象 - 抽象部分"""
def __init__(self, color: Color):
self.color = color # 桥接的关键:持有实现部分的引用
@abstractmethod
def draw(self):
pass
class Circle(Shape):
"""具体抽象 - 圆形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的圆形")
class Rectangle(Shape):
"""具体抽象 - 矩形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的矩形")
class Triangle(Shape):
"""具体抽象 - 三角形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的三角形")
"""形状抽象 - 抽象部分"""
def __init__(self, color: Color):
self.color = color # 桥接的关键:持有实现部分的引用
@abstractmethod
def draw(self):
pass
class Circle(Shape):
"""具体抽象 - 圆形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的圆形")
class Rectangle(Shape):
"""具体抽象 - 矩形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的矩形")
class Triangle(Shape):
"""具体抽象 - 三角形"""
def draw(self):
color_name = self.color.apply_color()
print(f"绘制{color_name}的三角形")
步骤 3:使用桥接模式
实例
# 客户端代码
def main():
# 创建颜色实现
red = Red()
blue = Blue()
green = Green()
# 创建形状抽象,并桥接颜色实现
red_circle = Circle(red)
blue_rectangle = Rectangle(blue)
green_triangle = Triangle(green)
# 绘制图形
print("=== 图形绘制结果 ===")
red_circle.draw() # 输出:绘制红色的圆形
blue_rectangle.draw() # 输出:绘制蓝色的矩形
green_triangle.draw() # 输出:绘制绿色的三角形
# 灵活组合:红色矩形
red_rectangle = Rectangle(red)
red_rectangle.draw() # 输出:绘制红色的矩形
if __name__ == "__main__":
main()
def main():
# 创建颜色实现
red = Red()
blue = Blue()
green = Green()
# 创建形状抽象,并桥接颜色实现
red_circle = Circle(red)
blue_rectangle = Rectangle(blue)
green_triangle = Triangle(green)
# 绘制图形
print("=== 图形绘制结果 ===")
red_circle.draw() # 输出:绘制红色的圆形
blue_rectangle.draw() # 输出:绘制蓝色的矩形
green_triangle.draw() # 输出:绘制绿色的三角形
# 灵活组合:红色矩形
red_rectangle = Rectangle(red)
red_rectangle.draw() # 输出:绘制红色的矩形
if __name__ == "__main__":
main()
实际应用场景
场景 1:消息发送系统
实例
from abc import ABC, abstractmethod
# 实现部分:消息发送方式
class MessageSender(ABC):
@abstractmethod
def send(self, message):
pass
class EmailSender(MessageSender):
def send(self, message):
return f"通过邮件发送:{message}"
class SMSSender(MessageSender):
def send(self, message):
return f"通过短信发送:{message}"
class WeChatSender(MessageSender):
def send(self, message):
return f"通过微信发送:{message}"
# 抽象部分:消息类型
class Message(ABC):
def __init__(self, sender: MessageSender):
self.sender = sender
@abstractmethod
def send(self):
pass
class UrgentMessage(Message):
def send(self):
message = "[紧急] " + self.get_content()
return self.sender.send(message)
def get_content(self):
return "系统出现异常,请立即处理!"
class NormalMessage(Message):
def __init__(self, sender: MessageSender, content):
super().__init__(sender)
self.content = content
def send(self):
return self.sender.send(self.content)
# 使用示例
def message_example():
email_sender = EmailSender()
sms_sender = SMSSender()
# 紧急消息通过短信发送
urgent_sms = UrgentMessage(sms_sender)
print(urgent_sms.send()) # 通过短信发送:[紧急] 系统出现异常,请立即处理!
# 普通消息通过邮件发送
normal_email = NormalMessage(email_sender, "月度报告已生成")
print(normal_email.send()) # 通过邮件发送:月度报告已生成
message_example()
# 实现部分:消息发送方式
class MessageSender(ABC):
@abstractmethod
def send(self, message):
pass
class EmailSender(MessageSender):
def send(self, message):
return f"通过邮件发送:{message}"
class SMSSender(MessageSender):
def send(self, message):
return f"通过短信发送:{message}"
class WeChatSender(MessageSender):
def send(self, message):
return f"通过微信发送:{message}"
# 抽象部分:消息类型
class Message(ABC):
def __init__(self, sender: MessageSender):
self.sender = sender
@abstractmethod
def send(self):
pass
class UrgentMessage(Message):
def send(self):
message = "[紧急] " + self.get_content()
return self.sender.send(message)
def get_content(self):
return "系统出现异常,请立即处理!"
class NormalMessage(Message):
def __init__(self, sender: MessageSender, content):
super().__init__(sender)
self.content = content
def send(self):
return self.sender.send(self.content)
# 使用示例
def message_example():
email_sender = EmailSender()
sms_sender = SMSSender()
# 紧急消息通过短信发送
urgent_sms = UrgentMessage(sms_sender)
print(urgent_sms.send()) # 通过短信发送:[紧急] 系统出现异常,请立即处理!
# 普通消息通过邮件发送
normal_email = NormalMessage(email_sender, "月度报告已生成")
print(normal_email.send()) # 通过邮件发送:月度报告已生成
message_example()
场景 2:设备遥控系统
实例
# 实现部分:设备
class Device(ABC):
@abstractmethod
def turn_on(self):
pass
@abstractmethod
def turn_off(self):
pass
@abstractmethod
def set_volume(self, volume):
pass
class TV(Device):
def turn_on(self):
return "电视已开启"
def turn_off(self):
return "电视已关闭"
def set_volume(self, volume):
return f"电视音量设置为:{volume}"
class Radio(Device):
def turn_on(self):
return "收音机已开启"
def turn_off(self):
return "收音机已关闭"
def set_volume(self, volume):
return f"收音机音量设置为:{volume}"
# 抽象部分:遥控器
class RemoteControl:
def __init__(self, device: Device):
self.device = device
def toggle_power(self):
return "切换电源状态"
def volume_up(self):
return "音量增加"
def volume_down(self):
return "音量减少"
class AdvancedRemoteControl(RemoteControl):
def mute(self):
return "静音模式"
def set_channel(self, channel):
return f"切换到频道:{channel}"
# 使用示例
def remote_example():
tv = TV()
radio = Radio()
basic_remote = RemoteControl(tv)
advanced_remote = AdvancedRemoteControl(radio)
print(basic_remote.toggle_power()) # 切换电源状态
print(advanced_remote.mute()) # 静音模式
remote_example()
class Device(ABC):
@abstractmethod
def turn_on(self):
pass
@abstractmethod
def turn_off(self):
pass
@abstractmethod
def set_volume(self, volume):
pass
class TV(Device):
def turn_on(self):
return "电视已开启"
def turn_off(self):
return "电视已关闭"
def set_volume(self, volume):
return f"电视音量设置为:{volume}"
class Radio(Device):
def turn_on(self):
return "收音机已开启"
def turn_off(self):
return "收音机已关闭"
def set_volume(self, volume):
return f"收音机音量设置为:{volume}"
# 抽象部分:遥控器
class RemoteControl:
def __init__(self, device: Device):
self.device = device
def toggle_power(self):
return "切换电源状态"
def volume_up(self):
return "音量增加"
def volume_down(self):
return "音量减少"
class AdvancedRemoteControl(RemoteControl):
def mute(self):
return "静音模式"
def set_channel(self, channel):
return f"切换到频道:{channel}"
# 使用示例
def remote_example():
tv = TV()
radio = Radio()
basic_remote = RemoteControl(tv)
advanced_remote = AdvancedRemoteControl(radio)
print(basic_remote.toggle_power()) # 切换电源状态
print(advanced_remote.mute()) # 静音模式
remote_example()
桥接模式的优势对比
| 特性 | 传统方式 | 桥接模式 |
|---|---|---|
| 扩展性 | 差,需要修改现有代码 | 好,可以独立扩展 |
| 类数量 | 多,容易类爆炸 | 少,线性增长 |
| 维护性 | 困难,牵一发而动全身 | 容易,职责分离 |
| 灵活性 | 固定组合 | 运行时动态组合 |
最佳实践和注意事项
使用时机
✅ 适合使用桥接模式的情况:
- 需要在多个维度上独立扩展时
- 需要在运行时切换实现时
- 避免永久性绑定 between abstraction and implementation 时
- 当继承会导致类层次结构过于复杂时
❌ 不适合的情况:
- 变化维度很少,不需要复杂设计时
- 抽象和实现之间有强耦合关系时
常见错误及避免方法
实例
# 错误示例:没有真正解耦
class BadShape:
def __init__(self, color_type):
if color_type == "red":
self.color = Red()
elif color_type == "blue":
self.color = Blue()
# 仍然需要修改这个类来添加新颜色
# 正确做法:依赖注入
class GoodShape:
def __init__(self, color: Color): # 依赖接口,而不是具体实现
self.color = color
class BadShape:
def __init__(self, color_type):
if color_type == "red":
self.color = Red()
elif color_type == "blue":
self.color = Blue()
# 仍然需要修改这个类来添加新颜色
# 正确做法:依赖注入
class GoodShape:
def __init__(self, color: Color): # 依赖接口,而不是具体实现
self.color = color
练习任务
练习 1:扩展图形系统
请为图形系统添加以下功能:
- 新增一种颜色(黄色)
- 新增一种形状(椭圆形)
- 创建黄色椭圆形并绘制
练习 2:设计支付系统
设计一个支付系统,要求:
- 支付方式:支付宝、微信支付、银行卡
- 支付类型:普通支付、分期支付、组合支付
- 使用桥接模式实现,确保支付方式和支付类型可以独立扩展
总结
桥接模式通过分离抽象和实现,提供了极大的灵活性。它的核心思想是:
- 识别变化维度:找出系统中可能独立变化的多个维度
- 建立桥梁:通过组合关系连接不同维度
- 独立扩展:每个维度都可以独立发展和变化
点我分享笔记