目的

将抽象部分与实现部分分离,使它们都可以独立地变化。

适用场景

在软件系统中,某些类型由于自身的逻辑,具有两个或多个维度的变化。面对这种"多维度的变化",就可以考虑使用桥接模式。

桥接模式的核心思路是让实现和接口解耦,把继承关系改为组合关系,从而应对多个实现的变化需求。C++ 中的 Impl 手法就是桥接模式的一种典型实现方式。

一个典型场景

下面通过一个逐步演化的例子来说明桥接模式要解决的问题:

  1. 客户给了你一个需求,于是使用一个类来实现(A)。
  2. 客户需求变化,出现两个算法来实现同一功能。于是改变设计:通过一个抽象基类,再定义两个具体类来实现两种不同的算法(A1 和 A2)。
  3. 客户又告诉我们要适配不同的操作系统。于是再抽象一个层次,作为一个抽象基类 A0,并分别为每个操作系统派生具体类(A00 和 A01,其中 A00 表示原来的类 A),实现不同操作系统上的客户需求。这样我们就有了一共 4 个类。
  4. 用户的需求可能还会继续变化,比如又多了一种新的算法……
  5. 我们陷入了一个需求不断变化的郁闷当中,也因此带来了类数量的迅速膨胀。

Bridge 模式正是解决了这一类问题。

例子 1

class AbstractionImpl
                {
                public:
                	virtual void Operation() = 0;
                
                
                };
                
                class AbstractionImplA :public AbstractionImpl
                {
                public:
                	virtual void Operation()override
                	{
                
                		cout << "do Action" << endl;
                	}
                
                
                };
                
                class Abstraction
                {
                public:
                	virtual void Operation() = 0;
                
                };
                
                
                
                
                
                class RefinedAbstrantion :public Abstraction
                {
                public:
                	virtual void Operation()override
                	{
                		impl->Operation();
                
                	}
                	RefinedAbstrantion(AbstractionImpl *impl)
                	{
                		this->impl = impl;
                
                	}
                private:
                	AbstractionImpl *impl;
                
                };
                
                
                
                
                
                
                
                
                int main(int argc, char *argv[])
                {
                
                	AbstractionImpl *impl = new AbstractionImplA;
                	Abstraction *abs = new RefinedAbstrantion(impl);
                
                	abs->Operation();
                
                
                
                	system("pause");
                	return 0;
                }
                //达到了  多个变化的维度,而不是通过简单的继承

例子 2:玩家和武器系统

 
                
                class Weapon
                {
                public:
                	virtual void use() = 0;
                
                };
                
                
                
                
                class WeaponImpl
                {
                public:
                
                	void use()
                	{
                		weapon->use();
                	}
                	WeaponImpl(Weapon* wea)
                	{
                		this->weapon = wea;
                	}
                private:
                	Weapon * weapon;
                };
                
                
                
                
                class Gun :public Weapon
                {
                public:
                	virtual void use()override
                	{
                		cout << "shoot" << endl;
                	}
                
                
                };
                
                
                class Player
                {
                public:
                
                
                	void EquipWeapon(WeaponImpl* weapon)
                	{
                		this->weaponImpl = weapon;
                	}
                	void useWeapon()
                	{
                		weaponImpl->use();
                	}
                private:
                
                	WeaponImpl *weaponImpl;
                
                
                
                };
                
                
                
                int main(int argc, char *argv[])
                {
                
                	WeaponImpl* impl = new WeaponImpl(new Gun);
                	Player *player = new Player;
                
                	player->EquipWeapon(impl);
                
                	player->useWeapon();
                
                	return 0;
                }