将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
桥接是用于把抽象化与实现化解耦,是的二者可以独立变化。它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个座位桥接的接口,使得实体类的功能独立于接口实现,这两种类型的类可被结构化改变而互不影响。
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
1. 介绍
意图:将抽象部分和实现部分分离,使他们都可以独立变化。
主要解决:再有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。
如何解决:把这种多角度分类分离出来,让他们独立变化,减少它们之间的耦合。
关键代码:抽闲类以来实现类。
应用实例:1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者响度昂与抽象化,后者相当于实现化。圣灵通过功能的委派,调用肉体对象的而功能,是的生灵可以动态选择。2、墙上的开关,可以看到的开关是抽象,不用管里面的具体实现。
优点:1、抽象和实现的分离。2、优秀的扩展能力。3、实现细节对客户透明。
缺点:桥接模式的映入会增加系统的理解和设计难度,由于聚合关联关系的建立在抽象层,要求开发者对抽象进行设计与编程。
使用场景:1、如果一个系统需要在构建的抽象化角色和具体化角色时间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使他们再抽象层建立一个关联关系。2、对于哪些不希望使用继承或因为多层次集成到窒息同类的个数急剧增加的系统,桥接模式尤为适用。3、一个类存在两个独立变化的维度,且这两个变化的维度都需要扩展。
注意事项:对于两个独立变化的维度,使用桥接模式在适合不过。
2. 实例
我们有一个作为桥接实现的 DrawAPI 接口和实现了 DrawAPI 接口的实体类 RedCircle、GreenCircle。Shape 是一个抽象类,将使用 DrawAPI 的对象。BridgePatternDemo 类使用 Shape 类来画出不同颜色的圆。
2.1. C++实现
#include <stdio.h>
#include <vector>
class drawApi {
public:
virtual void draw() = 0;
~drawApi(){}
};
class redCircle : public drawApi {
public:
void draw() {
printf("Draw red circle\n");
}
};
class greenCircle : public drawApi {
public:
void draw() {
printf("Draw green circle\n");
}
};
class shape {
public:
drawApi* drawApiMem;
shape(drawApi* api):drawApiMem(api){}
~shape(){}
};
class circle : public shape {
public:
circle(drawApi* api):shape(api){}
void draw()
{
printf("Circle shape draw\n");
drawApiMem->draw();
}
};
class rectgel : public shape {
public:
rectgel(drawApi* api):shape(api){}
void draw()
{
printf("Rector shape draw\n");
drawApiMem->draw();
}
};
#include<stdio.h>
#include "game.h"
int main(int argc, char** argv)
{
circle* cir = new circle(new redCircle());
cir->draw();
rectgel* rect = new rectgel(new greenCircle());
rect->draw();
while (1);
return 0;
}
3. 小结
Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固 有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
Bridge模式有时候类似于多继承方案,但是多继承方案往往违背 单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
Bridge模式的应用一般在“两个非常强的变化维度”,有时一个 类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。