Python 中的桥接模式(Bridge Pattern)

桥接模式是一种结构型设计模式,其核心目的是:
将抽象部分(Abstraction)与实现部分(Implementation)分离,使它们可以独立变化

形象比喻:就像一座桥连接两岸——“抽象”和“实现”本来紧密耦合,通过桥接模式把它们分开,让两岸各自发展而不互相影响。

为什么需要桥接模式?

如果不使用桥接模式,当抽象和实现都有多个变体时,会产生类爆炸(Cartesian product):

例如:形状(圆、正方形) × 渲染方式(矢量、光栅) → 需要 2 × 2 = 4 个类
如果再加一种形状或一种渲染方式,就需要新增更多类。

桥接模式通过组合而不是继承来解决这个问题。

典型应用场景
  • GUI 框架:窗口抽象 vs 不同平台实现(Windows、Mac、Linux)
  • 绘图程序:形状抽象 vs 渲染器(矢量、像素、光追)
  • 驱动程序:设备抽象 vs 不同协议实现
  • 消息发送:消息类型(文本、图片) vs 发送渠道(邮件、短信、推送)
Python 实现示例:形状 + 渲染器
from abc import ABC, abstractmethod

# === 实现部分(Implementation)===
class Renderer(ABC):
    @abstractmethod
    def render_circle(self, radius: float):
        pass

    @abstractmethod
    def render_square(self, side: float):
        pass

# 具体实现1:矢量渲染
class VectorRenderer(Renderer):
    def render_circle(self, radius: float):
        print(f"矢量渲染:绘制半径为 {radius} 的圆")

    def render_square(self, side: float):
        print(f"矢量渲染:绘制边长为 {side} 的正方形")

# 具体实现2:光栅渲染(像素)
class RasterRenderer(Renderer):
    def render_circle(self, radius: float):
        print(f"光栅渲染:绘制半径为 {radius} 的圆(像素点)")

    def render_square(self, side: float):
        print(f"光栅渲染:绘制边长为 {side} 的正方形(像素填充)")

# === 抽象部分(Abstraction)===
class Shape(ABC):
    def __init__(self, renderer: Renderer):
        self.renderer = renderer  # 通过组合持有实现

    @abstractmethod
    def draw(self):
        pass

    @abstractmethod
    def resize(self, factor: float):
        pass

# 细化抽象:圆
class Circle(Shape):
    def __init__(self, renderer: Renderer, radius: float):
        super().__init__(renderer)
        self.radius = radius

    def draw(self):
        self.renderer.render_circle(self.radius)

    def resize(self, factor: float):
        self.radius *= factor
        print(f"圆形调整大小:新半径 {self.radius}")

# 细化抽象:正方形
class Square(Shape):
    def __init__(self, renderer: Renderer, side: float):
        super().__init__(renderer)
        self.side = side

    def draw(self):
        self.renderer.render_square(self.side)

    def resize(self, factor: float):
        self.side *= factor
        print(f"正方形调整大小:新边长 {self.side}")

# 客户端使用
if __name__ == "__main__":
    # 可以自由组合抽象和实现
    vector = VectorRenderer()
    raster = RasterRenderer()

    circle1 = Circle(vector, 5)
    circle1.draw()          # 矢量圆
    circle1.resize(2)
    circle1.draw()

    circle2 = Circle(raster, 10)
    circle2.draw()          # 光栅圆

    square = Square(vector, 4)
    square.draw()

    # 切换渲染器非常容易
    another_circle = Circle(raster, 3)
    another_circle.draw()

输出

矢量渲染:绘制半径为 5 的圆
圆形调整大小:新半径 10.0
矢量渲染:绘制半径为 10.0 的圆
光栅渲染:绘制半径为 10 的圆(像素点)
矢量渲染:绘制边长为 4 的正方形
光栅渲染:绘制半径为 3 的圆(像素点)

现在新增一种形状(如 Triangle)只需继承 Shape,新增一种渲染器(如 OpenGLRenderer)只需实现 Renderer 接口,无需修改现有代码

桥接模式结构总结
角色 说明
Abstraction 抽象类(Shape),持有 Implementation 引用
RefinedAbstraction 细化抽象(Circle、Square)
Implementor 实现接口(Renderer)
ConcreteImplementor 具体实现(VectorRenderer、RasterRenderer)
桥接模式 vs 其他模式对比
模式 目的 组合 vs 继承 典型场景
桥接 分离抽象与实现,独立变化 组合 多维度变化(如平台+功能)
适配器 接口转换 组合 整合不兼容接口
策略 算法可替换 组合 行为变化
装饰器 动态添加职责 组合 功能增强
Python 中的实用建议
  • Python 是动态语言,桥接模式实现非常自然(通过组合注入实现)。
  • 常与依赖注入结合使用。
  • 在 GUI、游戏引擎、跨平台库中非常常见(如 PyQt/PySide 的后台实现)。
  • 不要与继承混用过度——桥接强调“组合优于继承”。
更现实的例子:消息发送系统
class MessageSender(ABC):
    @abstractmethod
    def send(self, message: str):
        pass

class EmailSender(MessageSender):
    def send(self, message: str):
        print(f"通过 Email 发送: {message}")

class SMSSender(MessageSender):
    def send(self, message: str):
        print(f"通过 SMS 发送: {message}")

class Message(ABC):
    def __init__(self, sender: MessageSender):
        self.sender = sender

    @abstractmethod
    def prepare(self) -> str:
        pass

    def send_message(self):
        content = self.prepare()
        self.sender.send(content)

class TextMessage(Message):
    def __init__(self, sender, text):
        super().__init__(sender)
        self.text = text

    def prepare(self):
        return f"文本消息: {self.text}"

class UrgentMessage(Message):
    def prepare(self):
        return f"【紧急】{self.text.upper()}!!!"

# 使用:自由组合
email_text = TextMessage(EmailSender(), "会议通知")
email_text.send_message()

sms_urgent = UrgentMessage(SMSSender(), "火警警报")
sms_urgent.send_message()

桥接模式是处理多维度变化的强大工具,在大型系统设计中非常有用

如果你想看更复杂的例子(如 GUI 跨平台桥接、数据库驱动桥接),或者与其他模式(如抽象工厂)结合使用,欢迎继续问!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐