设计模式之Bridge模式的C++实现

目录

1、Bridge模式的提出

2、Bridge模式的定义

3、Bridge模式总结

4、需求描述

5、多继承方式实现

6、使用Bridge设计模式实现


1、Bridge模式的提出

在软件功能模块设计中,如果类的实现功能划分不清晰,使得继承得到的子类往往是随着需求的变化,子类急剧膨胀,充斥重复代码。将类要实现功能划分清楚是设计较好软件框架的关键。

2、Bridge模式的定义

对于类的实现功能具有两个变化的维度,甚至由多个维度的变化,使用类的多继承实现方式,会使子类数目急剧膨胀。Bridge模式使用"对象间的组合关系"解耦抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度变化,即将不同的维度分别进行抽象,然后各自根据变化维度进行继承。

3、Bridge模式总结

Bridge模式的应用一般在"两个非常强的变化维度",有时一个类甚至有多个变化的维度,这时使用Bridge模式的扩展模式来设计代码。

4、需求描述

手机有固有属性(材料、颜色、摄像头个数)和软件属性(开机动画、网络打印、支持app数目)。有2款A、B类型手机,A、B分别继承手机的固有属性功能。在A款基础上又有2款Higher、Pro类型,Higher、Pro分别继承手机的软件功能;在B款的基础上也有2种Higher、Pro,这2种也分别继承手机的软件功能。

5、多继承方式实现

cpp 复制代码
#include <iostream>


class MobilePhone
{
public:
    //手机材质
    virtual void PhoneMaterial()=0;
    //手机颜色
    virtual void PhoneColor()=0;
    //手机大小
    virtual void PhoneCameNum()=0;

    //开机动画
    virtual void BootAnimation()=0;
    //网络打印类型
    virtual void NetPrintType()=0;
    //软件支持数目
    virtual void SoftSuppotNum()=0;

    virtual ~MobilePhone(){
    };


};

//下面的类继承关系中,不同层级的类继承不同抽象函数,可以分函数抽象一个类,见Bridge模式。

class APhoneNoraml:public MobilePhone
{
public:
    virtual ~APhoneNoraml(){};

    virtual void PhoneMaterial()override{
        std::cout << "Glass material" << std::endl;
    };

    virtual void PhoneColor()override{
        std::cout << "2 Colors" << std::endl;
    };

    virtual void PhoneCameNum()override{
        std::cout << "2 CamNum" << std::endl;
    };
};

class BPhoneNoraml:public MobilePhone
{
public:
    virtual ~BPhoneNoraml(){};

    virtual void PhoneMaterial()override{
        std::cout << "Glass material" << std::endl;
    };

    virtual void PhoneColor()override{
        std::cout << "3 Colors" << std::endl;
    };

    virtual void PhoneCameNum()override{
        std::cout << "3 CamNum" << std::endl;
    };
};


class APhoneHiger:public APhoneNoraml
{
public:
    virtual ~APhoneHiger(){};

    virtual void BootAnimation()override{
        APhoneNoraml::PhoneMaterial();
        APhoneNoraml::PhoneColor();
        APhoneNoraml::PhoneCameNum();
        std::cout << "good luck" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base txt type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 20 app" << std::endl;
    };
};

class BPhoneHiger:public BPhoneNoraml
{
public:
    virtual ~BPhoneHiger(){};

    virtual void BootAnimation()override{
        BPhoneNoraml::PhoneMaterial();
        BPhoneNoraml::PhoneColor();
        BPhoneNoraml::PhoneCameNum();
        std::cout << "gook lunck" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base txt type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 20 app" << std::endl;
    };

};

class APhonePro:public APhoneNoraml
{
public:
    virtual ~APhonePro(){};

    virtual void BootAnimation()override{
        APhoneNoraml::PhoneMaterial();
        APhoneNoraml::PhoneColor();
        APhoneNoraml::PhoneCameNum();
        std::cout << "best wishes" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base 3 type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 30 app" << std::endl;
    };
};

class BPhonePro:public BPhoneNoraml
{
public:
    virtual ~BPhonePro(){};

    virtual void BootAnimation()override{
        BPhoneNoraml::PhoneMaterial();
        BPhoneNoraml::PhoneColor();
        BPhoneNoraml::PhoneCameNum();
        std::cout << "best wishes" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base 3 type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 30 app" << std::endl;
    };

};

int main()
{
    MobilePhone* higherA = new APhoneHiger();
    higherA->BootAnimation();
    higherA->NetPrintType();
    higherA->SoftSuppotNum();
    delete higherA;
    higherA = nullptr;


    MobilePhone* proA = new APhonePro();
    proA->BootAnimation();
    proA->NetPrintType();
    proA->SoftSuppotNum();
    delete proA;
    proA = nullptr;
    return 0;
}

运行结果如下:

6、使用Bridge设计模式实现

cpp 复制代码
#include <iostream>

//将第一个变化维度的三个函数抽象成一个类,供第二层继承使用
class MobilePhone
{
public:
    //手机材质
    virtual void PhoneMaterial()=0;
    //手机颜色
    virtual void PhoneColor()=0;
    //手机大小
    virtual void PhoneCameNum()=0;
    virtual ~MobilePhone(){}
};

//将第二个变化维度的三个函数抽象出一个类,供第三层继承使用
class MobileSoft
{
public:
    MobileSoft(MobilePhone* p):Imp(p){};
    MobilePhone *Imp;
    //开机动画
    virtual void BootAnimation()=0;
    //网络打印类型
    virtual void NetPrintType()=0;
    //软件支持数目
    virtual void SoftSuppotNum()=0;
};

class APhoneNoraml:public MobilePhone
{
public:
    virtual ~APhoneNoraml(){};

    virtual void PhoneMaterial()override{
        std::cout << "Glass material" << std::endl;
    };

    virtual void PhoneColor()override{
        std::cout << "2 Colors" << std::endl;
    };

    virtual void PhoneCameNum()override{
        std::cout << "2 CamNum" << std::endl;
    };
};

class BPhoneNoraml:public MobilePhone
{
public:
    virtual ~BPhoneNoraml(){};

    virtual void PhoneMaterial()override{
        std::cout << "Glass material" << std::endl;
    };

    virtual void PhoneColor()override{
        std::cout << "3 Colors" << std::endl;
    };

    virtual void PhoneCameNum()override{
        std::cout << "3 CamNum" << std::endl;
    };
};

//在第三层继承关系处使用对象组合。
class PhoneHiger:public MobileSoft
{
public:
    PhoneHiger(MobilePhone *p):MobileSoft(p){};
    virtual ~PhoneHiger(){};

    virtual void BootAnimation()override{
        Imp->PhoneMaterial();
        Imp->PhoneColor();
        Imp->PhoneCameNum();
        std::cout << "good luck" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base txt type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 20 app" << std::endl;
    };
};


class PhonePro:public MobileSoft
{
public:
    PhonePro(MobilePhone *p):MobileSoft(p){};
    virtual ~PhonePro(){};

    virtual void BootAnimation()override{
        Imp->PhoneMaterial();
        Imp->PhoneColor();
        Imp->PhoneCameNum();
        std::cout << "best wishes" << std::endl;
    };

    virtual void NetPrintType()override{
        std::cout << "Support base 3 type" << std::endl;
    };

    virtual void SoftSuppotNum()override{
        std::cout << "Support 30 app" << std::endl;
    };
};

int main()
{
    std::cout << " ************** PhoneHiger ************** " << std::endl;
    MobilePhone *normalA = new APhoneNoraml();
    MobileSoft *higherA = new PhoneHiger(normalA);
    higherA->BootAnimation();
    higherA->NetPrintType();
    higherA->SoftSuppotNum();

    std::cout << "\n ************** PhonePro ************** " << std::endl;
    MobilePhone *normalPro = new APhoneNoraml();
    MobileSoft *proA = new PhonePro(normalPro);
    proA->BootAnimation();
    proA->NetPrintType();
    proA->SoftSuppotNum();
    return 0;
}

运行结果如下:

上面的代码将不同的变化维度分别抽象成一个类,供子类继承;并且其中一个维度的继承关系用"类成员是基类对象"组合的方式进行替代,使功能类代码具有良好的扩展性,也遵循单一职责原则。

相关推荐
杨充8 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充8 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充8 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充9 小时前
2.面向对象的特性
设计模式
杨充9 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充9 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充9 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯12 小时前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯20 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式