• 设计模式——桥接模式


    桥接模式(Bridge)

      在学习面向对象的过程中,可能会陷入一个误区,只要可以用,都用上继承,就好比因为有了新锤子,看什么东西都像是钉子了。
      事实上,继承可能会带来一些麻烦。比如对象的继承关系是在编译阶段就定义好的,所以无法在运行时改变从父类继承的实现。子类的实现与其父类有非常紧密的依赖关系,父类的变化必然导致子类的变化。当需要复用子类的时候,如果继承下来的实现不适用于解决新的问题,则父类必须重写或用更合适的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

    合成(Composition)/聚合(Aggregation)复用原则(CARP)

      尽量使用合成/聚合,尽量不要使用类继承。

      这就是为什么说多用组合,少用继承。

      聚合表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但是B对象不是A对象的一部分;
    合成也叫组合,是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期是一样的。
    大雁和翅膀是整体和部分的关系,生命周期一样,所以是组合关系。
    大雁属于一个雁群,所以是聚合关系。

    在这里插入图片描述

      合成/聚合复用原则的好处是:优先使用对象的合成/聚合有助于保持每个类被封装,并且集中在单个任务上。这样类和类继承层次会保持较小的规模,不容易发展成庞然大物。

    桥接模式

      将抽象部分与它的实现部分分离,使他们都可以独立地变化

      例如手机既可以按照品牌分类,也可以按照功能分类。

    在这里插入图片描述

      桥接模式的核心意图就是把这些实现独立出来,让他们各自变化,这样每种实现的变化都不会影响其他实现,从而达到应对变化的目的

    在这里插入图片描述

    #include 
    #include 
    
    using namespace std;
    
    // 手机软件类
    class HandsetSoft
    {
    public:
        virtual void Run() = 0;
    };
    
    // 手机游戏
    class HandsetGame : public HandsetSoft
    {
    public:
        void Run() override
        {
            cout << "运行手机游戏" << endl;
        }
    };
    
    // 手机通讯录
    class HandsetAddressList : public HandsetSoft
    {
    public:
        void Run() override
        {
            cout << "运行手机通讯录" << endl;
        }
    };
    
    // 手机品牌类
    class HandsetBrand
    {
    public:
        // 设置手机软件
        void SetHandsetSoft(HandsetSoft *soft)
        {
            this->soft = soft;
        }
    
        // 运行手机软件
        virtual void Run() = 0;
    
    protected:
        HandsetSoft *soft;
    };
    
    // 两个具体的品牌类
    class HandsetBrandM : public HandsetBrand
    {
    public:
        void Run() override
        {
            soft->Run();
        }
    };
    
    class HandsetBrandN : public HandsetBrand
    {
    public:
        void Run() override
        {
            soft->Run();
        }
    };
    
    // 客户端代码
    void Client()
    {
        HandsetBrand *ab;
        ab = new HandsetBrandN();
    
        ab->SetHandsetSoft(new HandsetGame());
        ab->Run();
    
        ab->SetHandsetSoft(new HandsetAddressList());
        ab->Run();
    
        ab = new HandsetBrandM();
    
        ab->SetHandsetSoft(new HandsetGame());
        ab->Run();
    
        ab->SetHandsetSoft(new HandsetAddressList());
        ab->Run();
    }
    
    int main()
    {
        Client();
    
        return 0;
    }
    
    

      这个过程就像是拿到一台新手机,给它装各种软件一样。
      实现手机品牌与手机软件的解耦,这样我们可以方便地增减手机品牌,也可以方便地增减手机的功能。

  • 相关阅读:
    php foreach变量引用的问题
    RUST语言
    Vue脚手架初始化&脚手架结构分析
    对角线的输出
    Java中String类型的hashCode实现
    Spark VS Flink,大数据该学什么
    PowerBI 首购用户分析(Tableau经典案例复刻)
    6. 堪比JMeter的.Net压测工具 - Crank 实战篇 - 收集诊断跟踪信息与如何分析瓶颈
    Ansible自动化部署工具-组件及语法介绍
    MYSQL数据库-库/表操作
  • 原文地址:https://blog.csdn.net/weixin_42903300/article/details/139782530