桥接模式的核心在于理解好继承属于is-a的关系,当我们使用继承的时候先要在心里问自己一遍子类是不是一个父类,如果答案是否,那我们就要考虑如何重新定义父类实现更好的抽象,此时我们可以联想到合成/聚合关系,合成代表的是一种强的拥有关系,也就是B是A的一部分,比如大雁的翅膀是大雁的一部分。聚合代表的是一种弱的拥有关系,也就是A的对象可以包含B,但B不是A的一部分,比如一只大雁可以是一个雁群,但一个雁群可以有多只大雁。文中用手机软件和手机品牌的例子形象地解释了这种关系,无论我们是使用手机品牌或者手机软件作为抽象类,其子类都会变地十分庞大,当需要修改时也要修改多处,但我们通过聚合/合成的关系重新设计,将手机品牌设为抽象类,其中包含手机软件的抽象类,然后将两者设计为聚合关系,即手机品牌中包含手机软件,手机软件不是手机品牌的一部分,即使没有手机软件,也不会影响手机品牌。然后我们的抽象手机品牌就可以派生出不同的手机品牌,同样,手机软件也可以派生出不同的手机软件,当需要时就可以将不同的手机软件功能加入到不同的手机品牌中。C++的表示代码如下:
#include <iostream>
using namespace std;
class AbstractPhoneSoftware{
public:
virtual void RunSoftware() = 0;
virtual ~AbstractPhoneSoftware(){}
};
class Game:public AbstractPhoneSoftware{
public:
void RunSoftware()
{
cout << "Game Run" << endl;
}
};
class Book:public AbstractPhoneSoftware{
public:
void RunSoftware()
{
cout << "Book Run" <<endl;
}
};
class AbstractPhoneBrand{
public:
virtual void run() = 0;
virtual void SetSoftware(AbstractPhoneSoftware *software) = 0;
protected:
AbstractPhoneSoftware* m_pSoftware;
};
class Nokia:public AbstractPhoneBrand{
public:
void SetSoftware(AbstractPhoneSoftware *software)
{
m_pSoftware = software;
}
void run()
{
m_pSoftware->RunSoftware();
}
};
class iPhone:public AbstractPhoneBrand
{
public:
void SetSoftware(AbstractPhoneSoftware *software)
{
m_pSoftware = software;
}
void run()
{
m_pSoftware->RunSoftware();
}
};
int main(int argc,char** argv)
{
Nokia nokia;
iPhone iphone;
AbstractPhoneSoftware *game = new Game();
AbstractPhoneSoftware *book = new Book();
nokia.SetSoftware(game);
iphone.SetSoftware(book);
nokia.run();
iphone.run();
delete game;
game = nullptr;
delete book;
book = nullptr;
return 0;
}