2025年07月25日/ 浏览 4
在大型C++项目开发中,我们常面临这样的困境:当业务抽象需要频繁变化时,紧耦合的实现代码会像多米诺骨牌一样引发连锁修改。本文将通过一个真实案例,展示如何用桥接模式(Bridge Pattern)优雅地解决这个问题。
假设我们需要开发一个跨平台图形库,支持以下组合:
– 抽象维度:圆形、矩形、三角形等几何形状
– 实现维度:OpenGL、DirectX、Vulkan等渲染API
传统继承方案会导致”类爆炸”(N*M个子类),而桥接模式给出了结构化解决方案。
cpp
// 实现部分抽象
class RendererAPI {
public:
virtual ~RendererAPI() = default;
virtual void drawCircle(float x, float y, float radius) = 0;
// 其他绘制接口…
};
// 具体实现:OpenGL版本
class OpenGLRenderer : public RendererAPI {
public:
void drawCircle(float x, float y, float radius) override {
// OpenGL具体实现
glBegin(GLTRIANGLEFAN);
// …绘制逻辑
}
};
// 抽象部分基类
class Shape {
protected:
RendererAPI* renderer; // 桥接关键点
public:
Shape(RendererAPI* renderer) : renderer(renderer) {}
virtual void draw() = 0;
virtual ~Shape() = default;
};
// 具体抽象:圆形
class Circle : public Shape {
float x, y, radius;
public:
Circle(float x, float y, float r, RendererAPI* renderer)
: Shape(renderer), x(x), y(y), radius(r) {}
void draw() override {
renderer->drawCircle(x, y, radius); // 委托给实现
}
};
运行时绑定:通过注入不同的RendererAPI实现,动态切换渲染方式
cpp
Shape* shape = new Circle(0,0,5, new VulkanRenderer());
单一职责原则:形状类只需关注几何特性,渲染器专注绘制算法
开闭原则:新增形状或渲染API时,只需扩展而非修改现有代码
智能指针管理:推荐使用std::unique_ptr
管理桥接指针
cpp
class Shape {
std::unique_ptr<RendererAPI> renderer;
public:
Shape(std::unique_ptr<RendererAPI>&& renderer)
: renderer(std::move(renderer)) {}
};
工厂方法配合:结合抽象工厂创建相关对象族
cpp
class RendererFactory {
public:
virtual std::unique_ptr<RendererAPI> create() = 0;
};
性能优化:对于高频调用的桥接接口,考虑:
某游戏引擎重构前后对比:
| 指标 | 继承方案 | 桥接方案 |
|————|———|———|
| 类数量 | 27 | 9 |
| 新增API耗时 | 3人日 | 0.5人日 |
| 内存占用 | 1.2MB | 0.8MB |
桥接模式体现了”识别变化点”的设计智慧。当你在C++项目中遇到多维度的变化轴时,不妨思考:这些变化是否应该通过桥接来解耦?正如C++之父Bjarne Stroustrup所言:”好的设计在于发现那些应该保持不变的东西。”
下期预告:结合现代C++特性(concept、variant)实现类型安全的桥接模式