当前位置: 首页 > news >正文

【C++设计模式】第七篇:桥接模式(Bridge)

注意:复现代码时,确保 VS2022 使用 C++17/20 标准以支持现代特性。

抽象与实现的解耦之道


1. 模式定义与用途​​

核心思想​

  • ​桥接模式:将抽象部分与实现部分分离,使二者可以独立变化。​
  • 关键用途:
    ​1.拆分复杂继承树:避免因多维度扩展导致的类爆炸。
    ​2.运行时切换实现:动态组合不同的抽象与实现(如渲染引擎、数据存储方式)。
  • 经典场景​
    1.图形库:形状(抽象)与渲染API(实现)的组合。
    2.设备控制:遥控器(抽象)与电器设备(实现)的解耦。

2. 模式结构解析

+---------------------+          +---------------------+  
|      Abstraction     |          |   Implementor       |  
+---------------------+          +---------------------+  
| - impl: Implementor |<>------->| + operationImpl()   |  
| + operation(): void |          +---------------------+  
+---------------------+                    ^  
       ^                                    |  
       |                              +-----+-------------+  
       |                              |                   |  
+---------------------+      +-------------------+    +-------------------+  
| RefinedAbstraction  |      | ConcreteImplA     |    | ConcreteImplB     |  
+---------------------+      +-------------------+    +-------------------+  
| + operation()       |      | + operationImpl() |    | + operationImpl() |  
+---------------------+      +-------------------+    +-------------------+  

角色说明​

  1. Abstraction:抽象部分的基类,持有实现部分的引用。
  2. RefinedAbstraction:扩展抽象功能的具体类。
  3. Implementor:实现部分的接口。
  4. ConcreteImplementor:实现部分的具体类。

3. 简单示例:图形渲染引擎桥接​

​场景:形状与渲染API解耦

// 实现部分:渲染API接口  
class RenderAPI {  
public:  
    virtual void renderCircle(float x, float y, float radius) = 0;  
    virtual ~RenderAPI() = default;  
};  

// 抽象部分:形状基类  
class Shape {  
public:  
    Shape(RenderAPI& api) : api_(api) {}  
    virtual void draw() = 0;  
protected:  
    RenderAPI& api_;  
};  

// 客户端调用  
class Circle : public Shape {  
public:  
    Circle(RenderAPI& api, float x, float y, float r)  
        : Shape(api), x_(x), y_(y), radius_(r) {}  

    void draw() override {  
        api_.renderCircle(x_, y_, radius_);  
    }  
private:  
    float x_, y_, radius_;  
};  

4. 完整代码:多API与多形状支持​

步骤1:实现部分(渲染API)

// 实现接口  
class RenderAPI {  
public:  
    virtual void renderCircle(float x, float y, float radius) = 0;  
    virtual void renderRect(float x, float y, float w, float h) = 0;  
    virtual ~RenderAPI() = default;  
};  

// OpenGL实现  
class OpenGLAPI : public RenderAPI {  
public:  
    void renderCircle(float x, float y, float radius) override {  
        std::cout << "OpenGL渲染圆形:位置(" << x << "," << y << "), 半径" << radius << "\n";  
    }  
    void renderRect(float x, float y, float w, float h) override {  
        std::cout << "OpenGL渲染矩形:位置(" << x << "," << y << "), 尺寸" << w << "x" << h << "\n";  
    }  
};  

// Vulkan实现  
class VulkanAPI : public RenderAPI {  
public:  
    void renderCircle(float x, float y, float radius) override {  
        std::cout << "Vulkan渲染圆形:位置(" << x << "," << y << "), 半径" << radius << "\n";  
    }  
    void renderRect(float x, float y, float w, float h) override {  
        std::cout << "Vulkan渲染矩形:位置(" << x << "," << y << "), 尺寸" << w << "x" << h << "\n";  
    }  
};  

步骤2:抽象部分(形状与扩展)​

// 抽象基类(使用智能指针管理实现)  
class Shape {  
public:  
    Shape(std::shared_ptr<RenderAPI> api) : api_(api) {}  
    virtual void draw() = 0;  
    virtual ~Shape() = default;  
protected:  
    std::shared_ptr<RenderAPI> api_;  
};  

// 具体形状:圆形  
class Circle : public Shape {  
public:  
    Circle(std::shared_ptr<RenderAPI> api, float x, float y, float r)  
        : Shape(api), x_(x), y_(y), radius_(r) {}  

    void draw() override {  
        api_->renderCircle(x_, y_, radius_);  
    }  
private:  
    float x_, y_, radius_;  
};  

// 具体形状:矩形  
class Rectangle : public Shape {  
public:  
    Rectangle(std::shared_ptr<RenderAPI> api, float x, float y, float w, float h)  
        : Shape(api), x_(x), y_(y), width_(w), height_(h) {}  

    void draw() override {  
        api_->renderRect(x_, y_, width_, height_);  
    }  
private:  
    float x_, y_, width_, height_;  
};  

步骤3:客户端动态组合

int main() {  
    // 创建不同渲染API  
    auto opengl = std::make_shared<OpenGLAPI>();  
    auto vulkan = std::make_shared<VulkanAPI>();  

    // 动态组合形状与API  
    Circle glCircle(opengl, 10, 10, 5);  
    Circle vkCircle(vulkan, 20, 20, 8);  
    Rectangle glRect(opengl, 5, 5, 10, 6);  

    glCircle.draw();  
    // 输出:OpenGL渲染圆形:位置(10,10), 半径5  
    vkCircle.draw();  
    // 输出:Vulkan渲染圆形:位置(20,20), 半径8  
    glRect.draw();  
    // 输出:OpenGL渲染矩形:位置(5,5), 尺寸10x6  
}  

5. 优缺点分析

优点​​缺点
分离抽象与实现,减少继承层次增加类的数量
支持运行时动态切换实现需要设计合理的抽象接口
提升跨平台、跨模块的扩展性对简单场景可能过度设计

6. 调试与优化策略​

调试技巧(VS2022)​​

  1. 验证桥接连接
    draw()方法中设置断点,检查api_指针是否指向正确的实现对象。
  2. 多态类型识别
    使用typeid(*api_).name()输出实际类型(需启用RTTI)。​

性能优化​

  1. 缓存实现对象
    对频繁使用的实现(如OpenGLAPI)使用单例或对象池。
  2. 移动语义优化
// 使用移动语义传递渲染API所有权  
Shape(std::shared_ptr<RenderAPI>&& api) : api_(std::move(api)) {}  

相关文章:

  • @PostConstruct注解的作用
  • 基于websocket的多用户网页五子棋 --- 测试报告
  • 小微企业友好方案:低成本智能客服系统如何落地
  • C# 基础知识总结(持续更新中...)
  • 数据仓库建模方法论:起源、发展与深度对比解析
  • ICLR 2025|香港浸会大学可信机器学习和推理课题组专场
  • 密码学基础-Hash、MAC、HMAC 的区别与联系
  • 计算机毕业设计SpringBoot+Vue.js个人博客系统(源码+文档+PPT+讲解)
  • react 19版中路由react-router-dom v7版的使用
  • 厦大第三发:《DeepSeek大模型及其企业应用实践》
  • 1.Big-endian/ little endian大端对齐、小端对齐
  • Camera相关配置
  • 带宽管理组网配置
  • Web Snapshot 网页截图 模块代码详解
  • 生活反思公园散步与小雨遇记
  • MoE 架构:专家齐聚,智启未来 —— 解锁传统稠密模型的瓶颈
  • MongoDB 查询语句详解:以 `db.fs.files.find().sort({ _id: -1 }).limit(10)` 为例
  • excel的宏是什么
  • AI 实战5 - pytorch框架实现face检测
  • 如何快速的用pdfjs建立一个网页可以在线阅读你的PDF文件
  • “三个集中”之后:图说浦东新区28次撤乡并镇
  • 现场丨在胡适施蛰存等手札与文献间,再看百年光华
  • 沧州低空经济起飞:飞行汽车开启千亿赛道,通用机场布局文旅体验
  • MSCI中国指数5月调整:新增5只A股、1只港股
  • 陕西一村民被冒名贷款40余万续:名下已无贷款,将继续追责
  • 外企聊营商|特雷通集团:税务服务“及时雨”