动机(Motivation)
-
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度(功能类),乃至多个纬度的变化。
-
如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
模式定义
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。 ——《设计模式》GoF
要点总结
-
Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
-
Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
-
Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。
个人总结
-
桥接模式使两个功能类为组合关系,这样在实际使用过程中A就可以根据情况来动态调用B的具体功能。这就像桥一样,使两者相互联系起来。
-
业务功能个数为m,平台功能个数为n,则单纯的继承的总个数为m + m*n,使用桥接模式后的总个数为m+n。
#include <iostream>
using namespace std;
class IRabbitColor
{
public:
virtual void doSomething() = 0;
};
class IRabbit
{
public:
virtual ~IRabbit()
{
delete m_color;
m_color = nullptr;
};
virtual void show() = 0;
void setColor(IRabbitColor *color)
{
m_color = color;
}
protected:
IRabbitColor *m_color;//桥梁的作用,多态调用
};
class BigRabbit : public IRabbit
{
public:
~BigRabbit(){};
virtual void show()
{
cout << "Big Rabbit" << endl;
m_color->doSomething();
};
};
class MiddleRabbit : public IRabbit
{
public:
~MiddleRabbit(){};
virtual void show()
{
cout << "Middle Rabbit" << endl;
m_color->doSomething();
};
};
class SmallRabbit : public IRabbit
{
public:
~SmallRabbit(){};
virtual void show()
{
cout << "Small Rabbit" << endl;
m_color->doSomething();
};
};
class White : public IRabbitColor
{
public:
virtual void doSomething()
{
cout << "color is white" << endl;
};
};
class Black : public IRabbitColor
{
public:
virtual void doSomething()
{
cout << "color is black" << endl;
};
};
class Gray : public IRabbitColor
{
public:
virtual void doSomething()
{
cout << "color is gary" << endl;
};
};
int main()
{
IRabbit *big_rabbit = new BigRabbit;
big_rabbit->setColor(new White);
big_rabbit->show();
IRabbit *mid_rabbit = new MiddleRabbit;
mid_rabbit->setColor(new Black);
mid_rabbit->show();
delete big_rabbit;
delete mid_rabbit;
big_rabbit = nullptr;
mid_rabbit= nullptr;
return 0;
}
如果不用桥接模式的话,则大白兔、大黑兔、大灰兔、中白兔。。。小灰兔等九个都需要写出来。这个明显是不好的,违背了依赖倒置原则。