当前位置: 代码迷 >> 综合 >> 设计模式:Bridge
  详细解决方案

设计模式:Bridge

热度:84   发布时间:2023-12-08 09:12:03.0

Bridge-桥模式

由于某些类型的固有实现逻辑,使得类型具有多个变化维度。
考虑这个例子,需要实现通信设计。
设置有Message类型,有Login、SendMessage、SendPicture,以及PlaySound、DrawShape、WriteText、Connect。
平台支持方面,需要支持PC平台设计,同时需要支持Mobile平台设计。
平台间的差异在于播放声音、图形绘制、写入文本、链接网络等功能的不同,考虑实现PC、Mobile继承Message,并重写上述功能函数。
之后,需求需要实现平台的经典版与华丽版。
经典版用与实现普通需求,华丽版提供更多的功能。

版本1

class Messager{
    
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual ~Messager(){
    }
};//平台实现class PCMessagerBase : public Messager{
    
public:virtual void PlaySound(){
    //**********}virtual void DrawShape(){
    //**********}virtual void WriteText(){
    //**********}virtual void Connect(){
    //**********}
};class MobileMessagerBase : public Messager{
    
public:virtual void PlaySound(){
    //==========}virtual void DrawShape(){
    //==========}virtual void WriteText(){
    //==========}virtual void Connect(){
    //==========}
};//业务抽象class PCMessagerLite : public PCMessagerBase {
    
public:virtual void Login(string username, string password){
    PCMessagerBase::Connect();//........}virtual void SendMessage(string message){
    PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){
    PCMessagerBase::DrawShape();//........}
};class PCMessagerPerfect : public PCMessagerBase {
    
public:virtual void Login(string username, string password){
    PCMessagerBase::PlaySound();//********PCMessagerBase::Connect();//........}virtual void SendMessage(string message){
    PCMessagerBase::PlaySound();//********PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){
    PCMessagerBase::PlaySound();//********PCMessagerBase::DrawShape();//........}
};class MobileMessagerLite : public MobileMessagerBase {
    
public:virtual void Login(string username, string password){
    MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){
    MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){
    MobileMessagerBase::DrawShape();//........}
};class MobileMessagerPerfect : public MobileMessagerBase {
    
public:virtual void Login(string username, string password){
    MobileMessagerBase::PlaySound();//********MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){
    MobileMessagerBase::PlaySound();//********MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){
    MobileMessagerBase::PlaySound();//********MobileMessagerBase::DrawShape();//........}
};void Process(){
    //编译时装配Messager *m =new MobileMessagerPerfect();
}

这个设计的问题在于,PC、Mobile下的版本实现代码具有重复性,其本质都是调用了各自基类的功能函数。如PC下的经典版调其父类网络连接函数,Mobile下的经典版调其父类的网络连接函数。
使用组合替代继承,将各类平台版本实现类包含其基类指针。同时PC、Mobile类都继承自同一个类Message,所以最后改为包含Message*。为了消除代码重复性,将2个平台下的MessageLite合并为一个,同样MessagePerfect也可以合并为一个,让他们通过基类指针的运行时多态来支持未来的变化。
另一个问题,PCMessageBase和MobileMessageBase继承自Message,仅部分覆写音频播放、绘制图像等函数,而并不是全部覆写。原因是,这7个纯虚函数放在一个类中是不合适,需要做类的拆分。考虑将前三个与后四个函数放入不同的类(Messaget与新的MessageImp),在由各平台与各业务分别继承覆写。这里就出现了Message的两个维度,一个是平台维度,另一个是版本维度。
最后派生类同样的字段(基类指针MessageImp*)上提至基类。PCMessageBase、MobileMessageBase改为PCMessageImp与MobileMessageImp。

版本2

class Messager{
    
protected:MessagerImp* messagerImp;//...
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual ~Messager(){
    }
};class MessagerImp{
    
public:virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual MessagerImp(){
    }
};//平台实现 n
class PCMessagerImp : public MessagerImp{
    
public:virtual void PlaySound(){
    //**********}virtual void DrawShape(){
    //**********}virtual void WriteText(){
    //**********}virtual void Connect(){
    //**********}
};class MobileMessagerImp : public MessagerImp{
    
public:virtual void PlaySound(){
    //==========}virtual void DrawShape(){
    //==========}virtual void WriteText(){
    //==========}virtual void Connect(){
    //==========}
};//业务抽象 m//类的数目:1+n+mclass MessagerLite :public Messager {
    public:virtual void Login(string username, string password){
    messagerImp->Connect();//........}virtual void SendMessage(string message){
    messagerImp->WriteText();//........}virtual void SendPicture(Image image){
    messagerImp->DrawShape();//........}
};class MessagerPerfect  :public Messager {
    public:virtual void Login(string username, string password){
    messagerImp->PlaySound();//********messagerImp->Connect();//........}virtual void SendMessage(string message){
    messagerImp->PlaySound();//********messagerImp->WriteText();//........}virtual void SendPicture(Image image){
    messagerImp->PlaySound();//********messagerImp->DrawShape();//........}
};void Process(){
    //运行时装配MessagerImp* mImp=new PCMessagerImp();Messager *m =new Messager(mImp);
}

将平台实现与业务抽象分离,在运行时以组合的形式进行运行时装配。
这里个人觉得Message需要再写一个构造器,赋值MessageImp*并用于实现业务抽象上的多态,不然使用会出错。
出自C++设计模式

  相关解决方案