桥接模式的核心是将抽象与实现分离,使两者可独立变化;通过抽象类持有一个实现类指针,以组合替代继承,支持图形类型与绘图平台的任意组合,避免类爆炸。
桥接模式(Bridge Pattern)的核心是将抽象与实现分离,使两者可以独立变化。在 C++ 中,通常通过抽象基类定义接口,再用另一个抽象类封装实现细节,两者通过组合而非继承关联。
桥接模式包含四个角色:
假设我们要支持多种图形(圆、矩形)在不同平台(Windows、Linux)上绘制。若用继承,会爆炸式增长子类(CircleWin、CircleLinux、RectWin、RectLinux……)。桥接模式可解耦“图形类型”和“绘图平台”。
代码结构如下:
// 实现层接口
class DrawingAPI {
public:
virtual void drawCircle(double x, double y, double radius) = 0;
virtual ~DrawingAPI() = default;
};
// 具体实现:Windows 绘图
class WindowsAPI : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
std::cout << "Drawing Circle [x=" << x << ", y=" << y
<< ", radius=" << radius << "] on Windows\n";
}
};
// 具体实现:Linux 绘图
class LinuxAPI : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
std::cout << "Drawing Circle [x=" << x << ", y=" << y
<< ", radius=" << radius << "] on Linux\n";
}
};
// 抽象层:图形
class Shape {
protected:
DrawingAPI m_api; // 桥接点:持有实现类指针
public:
explicit Shape(DrawingAPI api) : m_api(api) {}
virtual void draw() = 0;
virtual ~Shape() = default;
};
// 具体图形:圆
class Circle : public Shape {
double m_x, m_y, m_radius;
public:
Circle(DrawingAPI* api, double x, double y, double radius)
: Shape(api), m_x(x), m_y(y), m_radius(radius) {}
void draw() override {
m_api->drawCircle(m_x, m_y, m_radius);
}};
// 使用示例
int main() {
DrawingAPI winApi = new WindowsAPI();
DrawingAPI linuxApi = new LinuxAPI();
Shape* circleOnWin = new Circle(winApi, 5.0, 3.0, 2.0);
Shape* circleOnLinux = new Circle(li
nuxApi, 10.0, 7.0, 4.0);
circleOnWin->draw(); // 输出 Windows 版本
circleOnLinux->draw(); // 输出 Linux 版本
delete circleOnWin;
delete circleOnLinux;
delete winApi;
delete linuxApi;
return 0;
}
桥接 vs 继承:为什么更灵活?
如果改用继承实现平台适配,每新增一种图形就要为每个平台写一个子类;而桥接后:
桥接不是万能的,适合以下场景:
实际项目中,推荐用 std::unique_ptr 替代裸指针,避免手动释放;也可将 DrawingAPI 设计为接口类,由工厂创建具体实现,进一步解耦。