在软件设计中,如果责任划分不清晰,需求的变化时,子类会急剧膨胀,代码会大量重复。此时,划分责任是最关键的做法。
定义
桥模式将“抽象部分”与“实现部分”分离,使它们独立的变化。
实例
先看下面代码存在的问题。(子类膨胀,重复代码)
在PC平台和Mobile平台分别实现文本和图片的生成和发送。
消息的基类如下:
class Messager
{
public:
virtual void SendText(string text) = 0;
virtual void SendPicture(string Image) = 0;
virtual void PlaySound() = 0;
virtual void DrawText() = 0;
virtual void DrawPicture() = 0;
virtual ~Messager(){}
};
PC平台的实现如下:
//PC平台
class PCMessager:public Messager
{
public:
virtual void PlaySound() override {}
virtual void DrawText() override {}
virtual void DrawPicture() override {}
virtual ~PCMessager(){}
};
//精简版
class PCMessagerLite :public PCMessager
{
public:
virtual void SendText(string text) override
{
PCMessager::DrawText();
}
virtual void SendPicture(string Image) override
{
PCMessager::DrawPicture();
}
virtual ~PCMessagerLite() {}
};
//完美版
class PCMessagerPerfect :public PCMessager
{
public:
virtual void SendText(string text) override
{
PCMessager::PlaySound();
PCMessager::DrawText();
}
virtual void SendPicture(string Image) override
{
PCMessager::PlaySound();
PCMessager::DrawPicture();
}
virtual ~PCMessagerPerfect(){}
};
Mobile平台的实现如下:
//Mobile平台
class MobileMessager :public Messager
{
public:
virtual void PlaySound()override {}
virtual void DrawText() override {}
virtual void DrawPicture() override {}
virtual ~MobileMessager(){}
};
//精简版
class MobileMessagerLite :public MobileMessager
{
public:
virtual void SendText(string text) override
{
MobileMessager::DrawText();
}
virtual void SendPicture(string Image) override
{
MobileMessager::DrawPicture();
}
virtual ~MobileMessagerLite(){}
};
//完美版
class MobileMessagerPerfect :public MobileMessager
{
public:
virtual void SendText(string text) override
{
MobileMessager::PlaySound();
MobileMessager::DrawText();
}
virtual void SendPicture(string Image) override
{
MobileMessager::PlaySound();
MobileMessager::DrawPicture();
}
virtual ~MobileMessagerPerfect() {}
};
上述代码中存在大量的重复代码,原因是将messager的两个方向上的变化混在了一起,使用了继承而不是组合的方式组织代码。
下面使用桥模式改进代码:
平台实现:
class MessagerImp
{
public:
virtual void PlaySound() = 0;
virtual void DrawText() = 0;
virtual void DrawPicture() = 0;
virtual ~MessagerImp() {}
};
//PC平台
class PCMessagerImp :public MessagerImp
{
public:
virtual void PlaySound()override {}
virtual void DrawText() override {}
virtual void DrawPicture() override {}
virtual ~PCMessagerImp() {}
};
//Mobile平台
class MobileMessagerImp :public MessagerImp
{
public:
virtual void PlaySound()override {}
virtual void DrawText() override {}
virtual void DrawPicture() override {}
virtual ~MobileMessagerImp() {}
};
业务实现:
class Messager
{
public:
virtual void SendText(string text) = 0;
virtual void SendPicture(string Image) = 0;
virtual ~Messager(){}
protected:
MessagerImp *messagerImp;
};
//精简版
class MessagerLite: public Messager
{
public:
virtual void SendText(string text) override
{
messagerImp->DrawText();
}
virtual void SendPicture(string Image) override
{
messagerImp->DrawPicture();
}
virtual ~MessagerLite() {}
};
//完美版
class MessagerPerfect: public Messager
{
public:
virtual void SendText(string text) override
{
messagerImp->PlaySound();
messagerImp->DrawText();
}
virtual void SendPicture(string Image) override
{
messagerImp->PlaySound();
messagerImp->DrawPicture();
}
virtual ~MessagerPerfect() {}
};
桥模式的类图如下:
总结
桥模式使用“对象间的组合关系”解耦了抽象和实现两个维度的变化。