概述
之前学习的适配器模式一般常用在开发中后期,这里的桥接模式一般用在开发前期设计系统框架时。属于结构型模式,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。
模式定义:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
UML类图:
桥接模式包含的角色:
Abstraction:抽象类,其中定义了一个Implermentor(实现类)的对象并维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
RefinedAbstraction:扩充抽象类,实现Abstraction中的抽象方法。
Implementor:实现类接口。
ConcreteImplementor:具体的实现类接口,实现不同的操作方法。
代码体现:
//实现将不同类型的数据库中的数据转换成各种格式(txt,pdf...)
//抽象类
class sqlAbstraction
{
public:
sqlAbstraction(Implementor* imp)
{
pImp = imp;
}
virtual void turnStyle() = 0;
private:
Implementor* pImp;
};
//扩充抽象类(Mysql数据库)
class mysqlAbstraction : public sqlAbstraction
{
public:
mysqlAbstraction(Implementor* imp)
{
pImp = imp;
}
void turnStyle()
{
cout<<"做了一些操作拿到了MySQL的数据"<<endl;
//转换数据格式,转成什么格式取决于传入的实现类对象是什么
pImp->turnMe();
}
private:
Implementor* pImp;
};
//扩充抽象类(Redis数据库)
class redisAbstraction : public sqlAbstraction
{
public:
redisAbstraction(Implementor* imp)
{
pImp = imp;
}
void turnStyle()
{
cout<<"做了一些操作拿到了Redis的数据"<<endl;
//转换数据格式,转成什么格式取决于传入的实现类对象是什么
pImp->turnMe();
}
private:
Implementor* pImp;
};
//实现类接口
class Implementor
{
public:
virtual void turnMe()=0;
};
//具体的实现类(txt格式)
class txtImplementor
{
public:
void turnMe()
{
cout << "转换成txt格式"<<endl;
}
};
//具体的实现类(pdf格式)
class txtImplementor
{
public:
void turnMe()
{
cout << "转换成pdf格式"<<endl;
}
};
//使用
int main()
{
//要把MySQL数据转换成txt格式
Implementor* imp = new txtImplementor();
Abstraction* mysqlAbstraction = new mysqlAbstraction(imp);
mysqlAbstraction->turnStyle();
//MySQL数据库数据转换成pdf格式
Implementor* imp1 = new pdfImplementor();
Abstraction* mysqlAbstraction1 = new mysqlAbstraction(imp);
mysqlAbstraction1->turnStyle();
//Redis数据库数据转换成txt格式
Implementor* imp2 = new txtImplementor();
Abstraction* redisAbstraction = new redisAbstraction(imp);
redisAbstraction->turnStyle();
//Redis数据库数据转换成pdf格式
Implementor* imp3 = new pdfImplementor();
Abstraction* redisAbstraction1 = new redisAbstraction(imp);
redisAbstraction1->turnStyle();
return 0;
}
优缺点及适用场景
优点:
1.分离抽象接口及其实现部分。让他们的子类排列组合从而获得多维度组合对象。
2.在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
3.桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。
缺点:
1.桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
2.桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。
适用场景:
1.如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2.“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
3.一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
4.对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
参考:https://blog.csdn.net/lovelion/article/details/7464208
ps:分享一个画UML类图的工具:https://www.processon.com/