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

news/2025/2/24 4:45:51

解释

桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式。
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组件)
•运行时需要切换实现(如:动态更换数据库驱动)
•避免多层次继承导致的类爆炸


http://www.niftyadmin.cn/n/5863968.html

相关文章

体育电竞比分网开发流程

开发一个体育电竞比分网的流程可以分为以下几个主要步骤&#xff1a; 1. 需求分析 目标用户&#xff1a;确定网站的主要用户群体&#xff0c;如体育迷、电竞爱好者等。 功能需求&#xff1a;列出网站需要实现的功能&#xff0c;如实时比分更新、赛事日程、新闻资讯、用户评论…

c++ std::vector使用笔记

std::vector 是 C 标准库中的一个动态数组容器&#xff0c;提供了丰富的接口来管理容量、插入、删除和访问元素。以下是对你提到的接口的详细说明和使用示例&#xff1a; 1. 容量相关接口 capacity(): 返回当前 vector 分配的存储空间大小&#xff08;以元素数量计&#xff09…

用Python实现Excel数据同步到飞书文档

目录 一、整体目标 二、代码结构拆解 三、核心逻辑讲解&#xff08;重点&#xff09; 1. 建立安全连接&#xff08;获取access_token&#xff09; 2. 定位文档位置 3. 数据包装与投递 四、异常处理机制 五、函数讲解 get_access_token() 关键概念解释 1. 飞书API访问…

在虚拟机中搭建Spark学习环境的完整指南

在大数据处理领域&#xff0c;Apache Spark作为一种强大的开源数据处理框架&#xff0c;因其高效性和灵活性而备受开发者青睐。为了更好地学习和实践Spark&#xff0c;许多初学者会选择在虚拟机中搭建Spark环境。本文将详细介绍如何在虚拟机中创建并配置Spark环境&#xff0c;从…

Oracle JDK、Open JDK zulu下载地址

一、Oracle JDK https://www.oracle.com/java/technologies/downloads/ 刚进去是最新的版本&#xff0c;往下滑可以看到老版本 二、Open JDK的 Azul Zulu https://www.azul.com/downloads/ 直接可以选版本等选项卡

某生产制造集团管理流程优化项目成功案例纪实

某生产制造集团管理流程优化项目成功案例纪实 ——打造数智化管理新体验&#xff0c;实现组织效率的飞跃 【客户行业】生产制造 【问题类型】流程管理 【客户背景】 某生产制造集团专注于高精度机械部件的研发与生产&#xff0c;服务于航空、汽车、医疗设备等多个高端制造…

tortoiseGit的使用和上传拉取

tortoiseGit的使用和上传拉取 下载TortoiseGit 通过网盘分享的文件&#xff1a;tortoiseGit.zip 链接: https://pan.baidu.com/s/1EOT_UsM9_OysRqXa8gES4A?pwd1234 提取码: 1234 在电脑桌面新建文件夹并进入 右击鼠标 将网址复制上去 用户名和密码是在git注册的用户名和…

【MyBatis】#{} 与 ${} 的区别(常见面试题)

目录 前言 预编译SQL和即时SQL 什么是预编译SQL&#xff1f; 什么是即时SQL&#xff1f; 区别 #{} 与 ${}的使用 防止SQL注入 什么是SQL注入&#xff1f; 原理 排序功能 模糊查询 总结#{}和${}的区别 前言 在前面的学习中&#xff0c;我们已经知道了如果SQL语句想…