桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:
- 第一种设计方案是为每一种形状都提供一套各种颜色的版本。
- 第二种设计方案是根据实际需要对形状和颜色进行组合
对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。
优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
使用场景: 1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。
//步骤 1 创建桥接实现接口 class DrawAPI { public: virtual void drawCirle(int radius, int x, int y) { } DrawAPI() {} ~DrawAPI() {} DrawAPI& operator=(const DrawAPI& e) { } }; //步骤 2 创建实现了 DrawAPI 接口的实体桥接实现类 class RedCircle : public DrawAPI { public: int flag; RedCircle() { flag = 1; } ~RedCircle() {} void drawCirle(int radius, int x, int y) { cout << "Drawing Circle color: red, radius: " << radius << ", x: " << x << ", " << y << endl; } private: }; class GreenCircle : public DrawAPI { public: int flag; GreenCircle() { flag = 2; } ~GreenCircle() {} void drawCirle(int radius, int x, int y) { cout << "Drawing Circle color: green, radius: " << radius << ", x: " << x << ", " << y << endl; } private: }; //步骤 3 使用 DrawAPI 接口创建抽象类 Shape class Shape { public: DrawAPI* drawAPI; virtual void draw() { } Shape() { drawAPI = NULL; } ~Shape() {} }; //步骤 4 创建实现了 Shape 接口的实体类 class Circle :public Shape { private: int x, y, radius; public: Circle() {} Circle(int x, int y, int radius, DrawAPI* drawapit) { drawAPI = drawapit; x = x; y = y; radius = radius; } void draw() { drawAPI->drawCirle(radius,x,y); } }; int main() { GreenCircle greencircle; Circle c1(100, 100, 10, &greencircle); Shape* shape1 = &c1; RedCircle redcircle; Circle c2(100, 100, 10, &redcircle); Shape* shape2 = &c2; shape1->draw(); shape2->draw(); return 0; }