C++ 桥接模式详解

桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。

概念解析

桥接模式的核心思想是:

  1. 解耦抽象与实现:将抽象部分和实现部分分离,使它们可以独立变化

  2. 组合优于继承:通过组合而不是继承来连接抽象和实现

  3. 多维度变化:适用于多个独立变化的维度

主要组成部分

  1. 抽象(Abstraction):定义抽象接口,维护一个指向实现者的引用

  2. 扩展抽象(Refined Abstraction):扩展抽象定义的接口

  3. 实现者(Implementor):定义实现类的接口

  4. 具体实现者(Concrete Implementor):实现实现者接口的具体类

代码示例

下面是一个完整的桥接模式示例,包含详细注释:

#include <iostream>
#include <memory>
#include <string>
#include <vector>

// 实现者接口:绘图API
class DrawingAPI {
public:
    virtual void drawCircle(double x, double y, double radius) = 0;
    virtual void drawRectangle(double x1, double y1, double x2, double y2) = 0;
    virtual ~DrawingAPI() = default;
};

// 具体实现者1:OpenGL绘图API
class OpenGLAPI : public DrawingAPI {
public:
    void drawCircle(double x, double y, double radius) override {
        std::cout << "OpenGL绘制圆形: 中心(" << x << "," << y << "), 半径" << radius << std::endl;
    }
    
    void drawRectangle(double x1, double y1, double x2, double y2) override {
        std::cout << "OpenGL绘制矩形: 左上(" << x1 << "," << y1 
                  << "), 右下(" << x2 << "," << y2 << ")" << std::endl;
    }
};

// 具体实现者2:Direct2D绘图API
class Direct2DAPI : public DrawingAPI {
public:
    void drawCircle(double x, double y, double radius) override {
        std::cout << "Direct2D绘制圆形: 中心(" << x << "," << y << "), 半径" << radius << std::endl;
    }
    
    void drawRectangle(double x1, double y1, double x2, double y2) override {
        std::cout << "Direct2D绘制矩形: 左上(" << x1 << "," << y1 
                  << "), 右下(" << x2 << "," << y2 << ")" << std::endl;
    }
};

// 抽象:形状
class Shape {
protected:
    std::unique_ptr<DrawingAPI> drawingAPI_;
    
public:
    explicit Shape(std::unique_ptr<DrawingAPI> api) 
        : drawingAPI_(std::move(api)) {}
    
    virtual void draw() = 0; // 绘制形状
    virtual void resize(double percentage) = 0; // 调整大小
    virtual ~Shape() = default;
};

// 扩展抽象1:圆形
class Circle : public Shape {
private:
    double x_, y_, radius_;
    
public:
    Circle(double x, double y, double radius, std::unique_ptr<DrawingAPI> api)
        : Shape(std::move(api)), x_(x), y_(y), radius_(radius) {}
    
    void draw() override {
        drawingAPI_->drawCircle(x_, y_, radius_);
    }
    
    void resize(double percentage) override {
        radius_ *= (1.0 + percentage / 100.0);
        std::cout << "圆形大小调整为: " << percentage << "%" << std::endl;
    }
    
    void move(double newX, double newY) {
        x_ = newX;
        y_ = newY;
        std::cout << "圆形移动到: (" << newX << "," << newY << ")" << std::endl;
    }
};

// 扩展抽象2:矩形
class Rectangle : public Shape {
private:
    double x1_, y1_, x2_, y2_;
    
public:
    Rectangle(double x1, double y1, double x2, double y2, std::unique_ptr<DrawingAPI> api)
        : Shape(std::move(api)), x1_(x1), y1_(y1), x2_(x2), y2_(y2) {}
    
    void draw() override {
        drawingAPI_->drawRectangle(x1_, y1_, x2_, y2_);
    }
    
    void resize(double percentage) override {
        double width = x2_ - x1_;
        double height = y2_ - y1_;
        
        width *= (1.0 + percentage / 100.0);
        height *= (1.0 + percentage / 100.0);
        
        x2_ = x1_ + width;
        y2_ = y1_ + height;
        
        std::cout << "矩形大小调整为: " << percentage << "%" << std::endl;
    }
};

// 客户端代码
int main() {
    std::cout << "=== 桥接模式演示 ===" << std::endl;
    
    // 创建不同绘图API的实现
    auto opengl = std::make_unique<OpenGLAPI>();
    auto direct2d = std::make_unique<Direct2DAPI>();
    
    // 创建使用不同API的形状
    std::vector<std::unique_ptr<Shape>> shapes;
    
    shapes.push_back(std::make_unique<Circle>(10, 10, 5, std::make_unique<OpenGLAPI>()));
    shapes.push_back(std::make_unique<Rectangle>(5, 5, 15, 15, std::make_unique<Direct2DAPI>()));
    shapes.push_back(std::make_unique<Circle>(20, 20, 8, std::make_unique<Direct2DAPI>()));
    shapes.push_back(std::make_unique<Rectangle>(10, 10, 20, 20, std::make_unique<OpenGLAPI>()));
    
    // 绘制并调整所有形状
    for (auto& shape : shapes) {
        shape->draw();
        shape->resize(50); // 放大50%
        shape->draw();
        std::cout << std::endl;
    }
    
    // 动态改变绘图API
    std::cout << "\n动态改变绘图API:" << std::endl;
    auto circle = std::make_unique<Circle>(30, 30, 10, std::make_unique<OpenGLAPI>()));
    circle->draw();
    
    // 切换到Direct2D
    circle = std::make_unique<Circle>(30, 30, 10, std::make_unique<Direct2DAPI>());
    circle->draw();
    
    return 0;
}

模式优势

  1. 分离抽象与实现:抽象和实现可以独立扩展,互不影响

  2. 提高可扩展性:可以独立地对抽象和实现进行扩展

  3. 减少子类数量:避免多层继承导致的类爆炸问题

  4. 开闭原则:符合开闭原则,可以扩展新的抽象和实现而不修改现有代码

  5. 隐藏实现细节:客户端只与抽象接口交互,不依赖具体实现

适用场景

  1. 当需要避免抽象和实现之间的永久绑定时

  2. 当抽象和实现都应该通过子类化进行扩展时

  3. 当对抽象的实现进行修改不应影响客户端代码时

  4. 当需要在运行时切换不同的实现时

  5. 当类存在多个独立变化的维度,且每个维度都需要进行扩展时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值