一、什么是桥接模式
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。从定义上看,和Builder模式的定义有点像,其实是有区别的,Builder模式是指自身类的创建与属性设置的分离,而桥接模式是指两个或多个不同的类,在不同维度上实现具体类对象的分离,即多个对象在不同维度各自自由扩展的一种模式。
Builder模式参考:
https://blog.csdn.net/LittleLittleFish_xyg/article/details/83653223
二、代码结构实现桥接模式
桥接模式侧重于多个维度间的联合,以达到解耦的效果,结构代码以两个维度作示范:
维度A及其子类:
class DimensionB;
class DimensionA
{
public:
virtual~DimensionA(){};
virtual void cfunA() = 0;
void setDimensionB(DimensionB*b){ m_B = b; };
DimensionB*m_B;
};
class DA1 :public DimensionA
{
public:
void cfunA(){};
};
class DAn :public DimensionA
{
public:
void cfunA(){};
};
维度B及其子类
class DimensionB
{
public:
virtual~DimensionB(){};
virtual void cfunB() = 0;
};
class DB1 :public DimensionB
{
public:
void cfunB(){};
};
class DBn :public DimensionB
{
public:
void cfunB(){};
};
客户端代码
DimensionB B = new DB1;
DimensionA A = new DA1;
A.setDimensionB(B);
A.m_B->cfunB();
delete B;
delete A;
通过聚合的方式,维度A具有维度B的实例,可以操作维度A、B的功能。
三、代码实现的注意事项
1、确定独立的两个或多个维度
2、确定聚合的拥有与被拥有的关系
3、A类具有B类的实例
4、若构造函数被私有化,请使用友元,确保A能使用B所允许使用的功能
四、桥接模式的使用方法
每次上下班总是遇到一点点店铺,买饮料时总是很多个性化的选择,如加糖,加冰等,各个属性都是提供各种选择,此时适合使用桥接模式。模拟大小中杯的饮料,可加糖的方案。
饮料类及子类:
class Sugar;
class Drink
{
public:
virtual void setSugar(Sugar*sugar)
{
m_Sugar = sugar;
}
virtual void Color() = 0;
virtual~Drink(){};
Sugar*m_Sugar;
};
class SmallDrink :public Drink
{
public:
void Color(){};
};
class MidDrink :public Drink
{
public:
void Color(){};
};
class BigDrink :public Drink
{
public:
void Color(){};
};
糖类及 子类:
class Sugar
{
public:
virtual~Sugar(){};
virtual void SweetLever() = 0;
int m_lever;
};
class NoSugar:public Sugar
{
public:
void SweetLever()
{
m_lever = 0;
};
};
class SmallSugar :public Sugar
{
public:
void SweetLever()
{
m_lever = 1;
};
};
class BigSugar :public Sugar
{
public:
void SweetLever()
{
m_lever = 2;
};
};
客户端代码:
Sugar *sugar = new BigSugar;
Drink*drink = new BigDrink;
drink->setSugar(sugar);
drink->m_Sugar->SweetLever();
delete drink;
delete sugar;
饮料类拥有sugar类的实例,两个维度自由组合,如大杯不加糖、小杯加少量糖等组合,灵活个性化选择、易于拓展。当系统中具备角色与属性多对多关系时选择桥接模式是不错的选择。
五、优缺点
优点:把每个类的抽象和实现分离,极大提供系统灵活性,各个实现类自由扩展,可动态选择具体实现类型
缺点:需要正确识别两个或多个独立变化的维度