桥接模式(Brige):将抽象部分和它的实现部分分离,使它们都可以独立的变化。
当一个抽象可能有多个实现时,通常用继承来协调它们;抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但有时候此方法不够灵活,因为继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分和实现部分独立的进行修改、扩充和重用;桥接模式把依赖具体实现,提升为依赖抽象,来完成对象和变化因素之间的低耦合,提高系统的可维护性和扩展性。桥接模式的主要目的是将一个对象的变化与其它变化隔离开,让彼此之间的耦合度最低。
- Abstraction:定义了抽象类的接口,并且维护一个指向Implementor实现类的指针;
- RefineAbstraction:扩充了Abstraction类的接口;
- AbstractionImp:定义了实现类的接口,这个接口不一定要与Abstraction的接口完全一致;实际上,这两个接口可以完全不同;
- ConcreteAbstractionImpA、ConcreteAbstractionImpB:实现了AbstractionImp定义的接口。
看到这里是不是感觉这个模式太熟悉了,因为在STL中这个设计模式使用的地方太多了,比如下面的红黑树设计:
实现类AbstractionImp的接口定义:
class AbstractionImp
{
public:
virtual void OperationImpl() = 0;
};
ConcreteAbstractionImpA具体的实现:
class ConcreteAbstractionImpA : public AbstractionImp
{
public:
void OperationImpl()
{
cout << "ConcreteAbstractionImpA::OperationImpl" << endl;
}
};
看一下抽象接口是如何使用具体的实现的:
class Abstraction
{
public:
Abstraction(AbstractionImp *pImpl) : m_pImpl(pImpl) {}
virtual void Operation() = 0;
protected:
AbstractionImp *m_pImpl; //在内部定义了一个具体的实现对象
};
RefineAbstraction实现:
class RedfinedAbstraction : public Abstraction
{
public:
RedfinedAbstraction(AbstractionImp *pImpl) : Abstraction(pImpl) {}
void Operation()
{
m_pImpl->OperationImpl();//调用具体的实现类对象方法
}
};
源码:
#include <iostream>
using namespace std;
class AbstractionImp
{
public:
virtual void OperationImpl() = 0;
};
class ConcreteAbstractionImpA : public AbstractionImp
{
public:
void OperationImpl()
{
cout << "ConcreteAbstractionImpA::OperationImpl" << endl;
}
};
class Abstraction
{
public:
Abstraction(AbstractionImp *pImpl) : m_pImpl(pImpl) {}
virtual void Operation() = 0;
protected:
AbstractionImp *m_pImpl;
};
class RedfinedAbstraction : public Abstraction
{
public:
RedfinedAbstraction(AbstractionImp *pImpl) : Abstraction(pImpl) {}
void Operation()
{
m_pImpl->OperationImpl();
}
};
int main(int argc, char *argv[])
{
AbstractionImp *pImplObj = new ConcreteAbstractionImpA();
Abstraction *pAbsObj = new RedfinedAbstraction(pImplObj);
pAbsObj->Operation();
delete pImplObj;
pImplObj = NULL;
delete pAbsObj;
pAbsObj = NULL;
return 0;
}
总结:
桥接模式使得抽象和实现进行了分离,抽象不用依赖于实现,让抽象和实现部分各自修改起来都很方便,使用组合(就是Abstraction类中包含了Implementor)的方式,降低了耦合度,同时也有助于分层,从而产生更好的结构化系统。