Python 桥接模式

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 跨平台桥接、数据库驱动桥接),或者与其他模式(如抽象工厂)结合使用,欢迎继续问!

文章已创建 3511

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部