结构型模式-Bridge模式(桥接模式)

发布于:2025-02-24 ⋅ 阅读:(17) ⋅ 点赞:(0)

解释

桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式。
Bridge模式核心思想将抽象与实现解耦,使二者可以独立变化。适用于一个类存在多个变化维度且需要灵活扩展的场景。

场景假设:图形渲染系统

支持不同形状(圆形、矩形)和不同渲染引擎(OpenGL、Vulkan)

1. 不使用Bridge模式(类爆炸)// 抽象层基类

class Shape {
public:
    virtual void draw() = 0;
};

// 具体实现组合导致类数量爆炸
class CircleOpenGL : public Shape {
public:
    void draw() override {
        cout << "OpenGL绘制圆形" << endl;
    }
};

class CircleVulkan : public Shape {
public:
    void draw() override {
        cout << "Vulkan绘制圆形" << endl;
    }
};

class RectangleOpenGL : public Shape {
public:
    void draw() override {
        cout << "OpenGL绘制矩形" << endl;
    }
};

class RectangleVulkan : public Shape {
public:
    void draw() override {
        cout << "Vulkan绘制矩形" << endl;
    }
};

// 客户端使用
Shape* circleGL = new CircleOpenGL();
Shape* rectVK = new RectangleVulkan();

缺点分析:

  1. 类数量爆炸:n种形状 × m种引擎 = n×m个类
  2. 难以扩展:新增引擎需要为所有形状创建新子类
  3. 违反开闭原则:修改引擎需要改动形状类

2. 使用Bridge模式(解耦抽象与实现)// 实现部分接口

class Renderer {
public:
    virtual void renderCircle(float radius) = 0;
    virtual void renderRectangle(float width, float height) = 0;
    virtual ~Renderer() = default;
};

// 具体实现
class OpenGLRenderer : public Renderer {
public:
    void renderCircle(float r) override {
        cout << "OpenGL绘制圆形,半径:" << r << endl;
    }
    void renderRectangle(float w, float h) override {
        cout << "OpenGL绘制矩形," << w << "x" << h << endl;
    }
};

class VulkanRenderer : public Renderer {
public:
    void renderCircle(float r) override {
        cout << "Vulkan绘制圆形,半径:" << r << endl;
    }
    void renderRectangle(float w, float h) override {
        cout << "Vulkan绘制矩形," << w << "x" << h << endl;
    }
};

// 抽象层
class Shape {
protected:
    Renderer* renderer; // Bridge关键:持有实现层引用
public:
    Shape(Renderer* r) : renderer(r) {}
    virtual void draw() = 0;
    virtual ~Shape() = default;
};

class Circle : public Shape {
private:
    float radius;
public:
    Circle(Renderer* r, float rad) : Shape(r), radius(rad) {}
    void draw() override {
        renderer->renderCircle(radius);
    }
};

class Rectangle : public Shape {
private:
    float width, height;
public:
    Rectangle(Renderer* r, float w, float h) : Shape(r), width(w), height(h) {}
    void draw() override {
        renderer->renderRectangle(width, height);
    }
};

// 客户端使用
Renderer* gl = new OpenGLRenderer();
Renderer* vk = new VulkanRenderer();

Shape* redCircle = new Circle(gl, 5.0f);
Shape* blueRect = new Rectangle(vk, 10, 20);
redCircle->draw();  // OpenGL绘制圆形,半径:5
blueRect->draw();   // Vulkan绘制矩形,10x20

核心优势:

  1. 解耦维度:形状与渲染引擎独立变化
  2. 扩展性:新增引擎只需实现Renderer接口
  3. 减少冗余:类数量降为n+m

关键对比

特性 Bridge模式 传统继承方式
类数量 ✅ n + m ❌ n × m
新增维度 ✅ 只需添加新实现/抽象 ❌ 需修改多处代码
运行时切换实现 ✅ 动态注入Renderer对象 ❌ 需创建新子类
代码复用 ✅ 通用逻辑在抽象层实现 ❌ 重复实现相似逻辑
系统复杂度 ❌ 需要理解双重抽象 ✅ 直观但冗余

模式缺点

  1. 设计复杂度增加:需要预先识别抽象与实现维度
  2. 间接调用开销:通过指针跳转影响性能(通常可忽略)
  3. 接口膨胀风险:Renderer接口需要覆盖所有形状操作

工程实践建议

// 使用智能指针管理资源
class Shape {
    unique_ptr<Renderer> renderer; // 独占所有权
public:
    Shape(unique_ptr<Renderer> r) : renderer(std::move(r)) {}
    // ...
};

// 创建组合对象
auto shape = make_unique<Circle>(
    make_unique<VulkanRenderer>(), 
    8.0f
);

适用场景:

•系统需要多维度扩展(如:跨平台UI组件)
•运行时需要切换实现(如:动态更换数据库驱动)
•避免多层次继承导致的类爆炸