目录
一、介绍
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。又称为柄体(Handle and Body)模式或接口(Interfce)模式。
类的功能层次结构:父类具有基本功能,在子类中增加新的功能;
类的实现层次结构:父类通过声明抽象方法来定义接口,子类通过实现具体方法来实现接口;
二、应用场景
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
对于两个独立变化的维度,使用桥接模式再适合不过了。
三、要点
将抽象部分与实现部分分离,使它们都可以独立的变化。
桥接模式中有四个角色:
抽象化角色:使用实现者角色提供的接口来定义基本功能接口。持有实现者角色,并在功能接口中委托给它,起到搭建桥梁的作用;抽象化角色并不是指它就是一个抽象类,而是指抽象了实现。
改善后的抽象化角色:作为抽象化角色的子类,增加新的功能,也就是增加新的接口(方法);与其构成类的功能层次结构;
实现者角色:提供了用于抽象化角色的接口;它是一个抽象类或者接口。
具体的实现者角色:作为实现者角色的子类,通过实现具体方法来实现接口;与其构成类的实现层次结构。
如果抽象和实现两者做不到独立地变化,就不算桥接模式。
四、样例
#include <iostream>
using namespace std;
class HandsetSoft
{
public:
virtual void Run() = 0;
virtual ~HandsetSoft(){}
};
class HandsetGame : public HandsetSoft
{
public:
void Run()
{
cout << "运行手机游戏" << endl;
}
~HandsetGame(){}
};
class HandsetAddressList : public HandsetSoft
{
public:
void Run()
{
cout << "运行手机通讯录" << endl;
}
~HandsetAddressList(){}
};
class HandsetBrand
{
protected:
HandsetSoft* soft;
public:
void SetHandsetSoft(HandsetSoft* soft)
{
this->soft = soft;
}
virtual void Run() = 0;
virtual ~HandsetBrand() {}
};
class HandsetBrandN : public HandsetBrand
{
public:
void Run()
{
soft->Run();
}
~HandsetBrandN() {}
};
class HandsetBrandM : public HandsetBrand
{
public:
void Run()
{
soft->Run();
}
~HandsetBrandM() {}
};
int main()
{
HandsetBrand* ab;
HandsetBrandN hbn;
HandsetGame hg;
ab = &hbn;
ab->SetHandsetSoft(&hg);
ab->Run(); // 运行手机游戏
HandsetAddressList hl;
ab->SetHandsetSoft(&hl);
ab->Run(); // 运行手机通讯录
HandsetBrandM hbm;
ab = &hbm;
ab->SetHandsetSoft(&hg);
ab->Run(); // 运行手机游戏
ab->SetHandsetSoft(&hl);
ab->Run(); // 运行手机通讯录
return 0;
}
五、优缺点
优点:
1、抽象和实现的分离。
2、优秀的扩展能力。
3、实现细节对客户透明。
缺点:
桥接模式的引入会增加系统的理解与设计难度,由于聚合关系建立在抽象层,要求开发者针对抽象进行设计与编程。
结构比较复杂。
抽象类的修改会影响到子类。
六、和适配器模式异同
同:都是让两个东西配合工作。
异:
适配器:改变已有的两个接口,让他们相容。适配是先有两边东西,才有适配器。
桥接模式:分离抽象化和实现,使两者的接口可以不同,目的是分离。桥接是先有“桥”,才有两端的东西。桥接在桥好了后,两边的东西还可以变化。