设计模式7——桥模式

动机

由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。
如何让轻松应对“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?


模式定义

将抽象部分(业务功能)与实现部分(平台实现)分离,使他们都可以独立变化
——《设计模式》GoF


案例

设计一个用于发送消息的平台,在基类定义了各种虚函数

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{//PC平台
public:   
    virtual void PlaySound(){
        //**********
    }
    virtual void DrawShape(){
        //**********
    }
    virtual void WriteText(){
        //**********
    }
    virtual void Connect(){
        //**********
    }
};
class MobileMessagerBase : public Messager{//Mobile平台
public: 
    virtual void PlaySound(){
        //==========
    }
    virtual void DrawShape(){
        //==========
    }
    virtual void WriteText(){
        //==========
    }
    virtual void Connect(){
        //==========
    }
};

上述代码只重写了基类中的基本的方法,其他的方法没有重写,因为比如virtual void Login()它可能是这些基本方法的组合。
针对这两个平台上,我们有精简版和完整版,区别就在于

 virtual void Login
 virtual void SendMessage
 virtual void SendPicture

这三个函数的不同;

class PCMessagerLite : public PCMessagerBase {//PC精简版
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 {//PC完整版
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 {//Mobile精简版
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 {//Mobile完整版
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();
}

也是编译时装配


改进

首先将基础功能函数和组合功能函数分隔开,这是因为组合功能函数大都包含基础功能函数。

//基础功能纯虚函数
class MessagerImp{
public:
    virtual void PlaySound()=0;
    virtual void DrawShape()=0;
    virtual void WriteText()=0;
    virtual void Connect()=0;
    virtual MessagerImp(){}//构造函数
};
//组合功能纯虚函数
class Messager{
protected:
     MessagerImp* messagerImp;//添加基础功能的对象指针
     Messager(MessagerImp* imp):messagerImp(imp){}
public:
    virtual void Login(string username, string password)=0;
    virtual void SendMessage(string message)=0;
    virtual void SendPicture(Image image)=0;
    virtual ~Messager(){}
};

然后实现PC和Mobile平台的基础功能函数,

//PC平台基础功能
class PCMessagerImp : public MessagerImp{
public:
    virtual void PlaySound(){
	  /**/
    }
    virtual void DrawShape(){
	  /**/
    }
    virtual void WriteText(){
  	/**/
    }
    virtual void Connect(){
 	 /**/
    }
};
//Mobile平台基础功能
class MobileMessagerImp : public MessagerImp{
public:
    virtual void PlaySound(){
        /**/
    }
    virtual void DrawShape(){
	  /**/
    }
    virtual void WriteText(){
	  /**/
    }
    virtual void Connect(){
 	 /**/
    }
};

然后实现完整版和精简版,这时不分平台

//业务抽象 m
//类的数目:1+n+m
class MessagerLite :public Messager {//软件精简版
public:
 MessagerImp* messagerImp;//这个在Messager类继承来
 MessagerLiter(MessagerImp* mesImp){//构造函数,根据传入的是PC还是Mobile类实现多态
  MessagerImp* messagerImp = mesImp;
 }
    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:
 MessagerPerfect(MessagerImp* mesImp){//构造函数
  MessagerImp* messagerImp = mesImp;
 }
    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();//PC和Mobile的实现方法不一样,父类指针指向子类对象实现多态
    Messager *m =new MessagerLite(mImp);
    m->sendMessage(1);
}

总结

  • Bridge模式使用“对象间的组合关系”解耦了抽象和现实之间固有的绑定关系,使得抽象和现实可以沿着各自的维度变化。所谓抽象和实现沿着各自的维度变化,即“子类化”他们。
  • Bridge模式有时类似于多继承方案,但是多继承方案往往违背单一职责原则,复用性差。
  • Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值