桥接模式
桥接模式:将抽象部分与实现部分分离,使它们都可以独立变换。桥接模式实质是因为某个对象有多个维度的变化因素;通过组合的方式将这多个维度的变化因子组合到一起。
桥接模式(Bridge)是一种结构型设计模式。基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。
主要特点是:
1.将实现(Implementation)抽离出来,再实现抽象(Abstraction),使得对象的具体实现依赖于抽象,满足了依赖倒转原则。
2.更好的可扩展性。
3.可动态的切换实现。桥接模式实现了抽象和实现的分离,在实现桥接模式时,就可以实现动态的选择具体的实现。
什么时候适合使用桥接模式?
总结一下网上和相关资料,以下情形可以考虑桥接模式:
1.一个对象有多个变化因素的时候,考虑依赖于抽象的实现,而不是具体的实现。
2.多个变化因素在多个对象间共享时,考虑将这部分变化的部分抽象出来再聚合/合成进来。
3.一个对象的多个变化因素可以动态变化的时候。
下面通过一个具体的案例来体现一下桥接模式的完整过程:
设:汽车的类型千千万,但有的车启动方式不一样,有汽油启动和电力启动,但不管它们的启动过程是如何的,都有一个共同点,都需要打开启动按钮(钥匙)。
因此:
1.公用接口就是启动,把启动做成接口并开放出来,供其他类具体实现。
2.各种各样的车从根本上来说都是车,作为第二个接口。
3.车和启动之间用桥接方式连接。
相关工程代码:
// Bridge.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include"iostream"
using namespace std;
//抽象类:StartMode---(启动方式),提供接口
class StartMode
{
public :
virtual ~StartMode(){cout<<"~StartMode()"<<endl; }
virtual void Start() = 0; //提供公用接口
};
//具体的StartMode启动实现类:汽油启动
class GasStart:public StartMode
{
public:
void Start() /实现Start()接口
{
cout<<"启动方式:汽油启动"<<endl;
}
};
//具体的StartMode启动实现类:电力启动
class ElectricStart:public StartMode
{
public:
void Start() //实现Start()口
{
cout<<"启动方式:电力启动"<<endl;
}
};
//抽象汽车类,提供接口
class CarType
{
public:
virtual ~CarType(){cout << "~CarType()" << endl;}
virtual void CarStart(StartMode* car) = 0; //实现启动方式StartMode与车型的桥接
};
//具体的汽车实现类:比亚迪
class BiYaDi:public CarType
{
public:
void CarStart(StartMode* startMode)
{
cout << "比亚迪: ";
startMode->Start();
}
};
//具体的汽车实现类:宝马
class BaoMa:public CarType
{
public:
void CarStart(StartMode* startMode)
{
cout << "宝马: ";
startMode->Start();
}
};
//主函数
int main()
{
StartMode* gasStart = new GasStart; //创建GasStart类对象
StartMode* electricStart = new ElectricStart; //创建ElectricStart类对象
BiYaDi* biyadi = new BiYaDi; //创建BiYaDi类对象:比亚迪车
BaoMa* bama =new BaoMa; //创建BaoMa类对象:宝马车
biyadi->CarStart(gasStart); //比亚迪的汽油启动方式
biyadi->CarStart(electricStart);//比亚迪的电力启动方式
bama->CarStart(gasStart); //宝马的汽油启动方式
bama->CarStart(electricStart); //宝马的电力启动方式
//指针用完后需要进行释放,否则内存泄漏
delete biyadi;
biyadi = NULL;
delete bama;
bama = NULL;
delete gasStart;
gasStart = NULL;
delete electricStart;
electricStart = NULL;
return 0;
}