桥接模式类似于抽象工厂模式。
抽象工厂将不同工厂生产的不同产品分离开来,这样,在使用某些特定产品时新建一个工厂即可,也可以很方便地对不同的产品进行修改,实现抽象与实现分离,即每个工厂的抽象与具体生产的产品细节分离。
桥接模式则相当于为每一种工厂的子类引入抽象的产品对象成员,使得每一个新建的工厂都能生产所有的产品,实现抽象与实现分离。
代码如下
#include <QCoreApplication>
#include <QList>
#include <QDebug>
///NOTE5桥接模式--最难理解的设计模式 --20190213
//常见的例子是不同品牌的手机运行不同的软件,或者不同的操作系统,这里
//尝试举一个新例子,即不同的车装不同的货物。
//可以看出,这样就成功封装了不同需求下(不同车子)执行一些设计好的功能(不同货物)而不需要为每个不同情况重新设计
//货物类的抽象,假设每件货物都有自报家门的功能
class Cargo
{
public:
virtual ~Cargo() {}
virtual void Say() = 0;
};
//一种货物--盒子
class Box: public Cargo
{
public:
void Say()
{
qDebug() << "I'm a box!";
}
};
//另一种货物--桶
class Bucket: public Cargo
{
public:
void Say()
{
qDebug() << "I'm a bucket!";
}
};
//载具类的抽象--载具拥有功能:装载
class Vehicle
{
public:
virtual void Load() = 0;
virtual ~Vehicle() {}
};
//一种载具--小车,可以装载所有货物
class Car: public Vehicle
{
public:
Car(Cargo *_cargo)
{
this->cargo = _cargo;
}
~Car()
{
}
void Load()
{
qDebug() << "What's car load?";
cargo->Say();
}
private:
Cargo *cargo;
};
//另一种载具--卡车,可以装载所有货物
class Truck: public Vehicle
{
public:
Truck(Cargo *_cargo)
{
this->cargo = _cargo;
}
~Truck()
{
}
void Load()
{
qDebug() << "What's truck load?";
cargo->Say();
}
private:
Cargo *cargo;
};
int main(int, char **)
{
Cargo *myBox = new Box();
Cargo *myBucket = new Bucket();
Vehicle *myCar = new Car(myBox);
Vehicle *myTruck = new Truck(myBucket);
myCar->Load();
myTruck->Load();
getchar();
delete myBox;
delete myBucket;
delete myCar;
delete myTruck;
return 0;
}
结果
增加一个常见的书中代码,感觉写的有点抽象,用上面的方式重新理解了一下
#include <iostream>
using namespace std;
// Abstraction
//抽象接口
class Abstraction
{
public:
virtual void Operation() = 0;
virtual ~Abstraction() {}
protected:
Abstraction() {}
};
// AbstractionImp
//抽象功能接口
class AbstractionImp : public Abstraction
{
public:
virtual void Operation() = 0;
virtual ~AbstractionImp() {}
protected:
AbstractionImp() {}
};
//实现功能接口
class ConcreteAbstractionImp : public AbstractionImp
{
public:
void Operation()
{
cout << "ConcreteAbstractionImp Operation..." << endl;
}
};
//重定义抽象接口,将抽象功能接口作为成员变量引入,修改功能为抽象功能接口的功能
class RefinedAbstraction : public Abstraction
{
public:
RefinedAbstraction(AbstractionImp *imp)
{
_imp = imp;
}
void Operation()
{
_imp->Operation();
}
private:
AbstractionImp *_imp;
};
int main()
{
//实例化实现功能接口
AbstractionImp *imp = new ConcreteAbstractionImp();
//实例化重定义抽象接口,将实现功能接口引入
Abstraction *abs = new RefinedAbstraction(imp);
//执行功能,这样就成功让重定义的功能接口执行了实现的功能
abs->Operation();
delete imp;
delete abs;
return 0;
}
按上面的例子来重新理解这篇代码:
1、一个抽象的载具类Abstraction拥有装载功能Operation
2、从载具类继承出一个小车类AbstractionImp
3、从小车继承一个小汽车类ConcreteAbstractionImp实现小车的装载功能
4、从载具类重新继承一个卡车类RefinedAbstraction,把小车作为成员引入,将小车的装载功能给卡车
5、实例化小汽车类(我的小汽车)和卡车类(我的卡车),将我的小汽车引入到我的卡车
6、执行我的卡车的装载功能,则成功连接上了我的小汽车的装载功能