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

news2024/11/14 6:03:00

目录

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、多继承方式实现

#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设计模式实现

#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;
}

运行结果如下:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/854534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring(11) Bean的生命周期

目录 一、简介二、Bean的流程1.BeanDefinition2.Bean 的生命周期 三、代码验证1.User 实体类2.MyBeanPostProcessor 后置处理器3.SpringConfig 扫描包配置4.UserTest 测试类5.测试结果6.模拟AOP增强 三、总结 一、简介 首先&#xff0c;为什么要学习 Spring 中 Bean 的生命周期…

数据请求与导入mysql数据库

端口数据获取与文件保存 文件存入数据库 系统&#xff1a;Ubuntu 工具&#xff1a;Postman&#xff0c;MySql Workbench 端口数据获取与文件保存 打开postman接口测试工具 选择请求方式输入请求地址选择请求参数设置请求参数的格式输入请求参数发送请求 请求成功 选择浏览…

修改IDEA的idea.vmoptions参数导致IDEA无法打开(ReservedCodeCacheSize)

事发原因 Maven导依赖的时候OOM&#xff0c;因此怀疑是内存太小&#xff0c;尝试修改idea.vmoptions的参数&#xff0c;然后发现IDEA重启后打不开了&#xff0c;卸载重装后也无法打开。。。 实际上如果导包爆出OOM的话应该调整下图参数&#xff0c;不过这都是后话了 解决思路…

制作UEFI启动盘

1.制作UEFI BIOS下的启动盘 设置好环境变量。 通过编译ShellPkg得到启动文件&#xff1a; C:\UEFIWorkspace>build -a IA32 -a X64 -p edk2\ShellPkg\ShellPkg.dsc -t VS2017 -b RELEASE 生成的执行文件路径&#xff1a; C:\UEFIWorkspace\Build\Shell\RELEASE_VS2017\…

CANoe通过Frame Histogram窗口统计报文周期(方便快捷)

文章目录 效果展示1.插入Frame Histogram窗口2.Activate3.运行CANoe&#xff0c;停止后查看write窗口 效果展示 统计报文周期信息输出在write窗口。 1.插入Frame Histogram窗口 2.Activate 3.运行CANoe&#xff0c;停止后查看write窗口 统计报文周期信息输出在write窗口。

爬虫学习记录(持续更新)

一、问题记录 1.使用webdriver报错AttributeError: str object has no attribute capabilities 解决&#xff1a;目前使用的selenium版本是4.11.2&#xff0c;可以不必设置driver.exe的路径&#xff0c;selenium可以自己处理浏览器和驱动程序&#xff0c;因此&#xff0c;使用…

SSRF(服务器端请求伪造)漏洞

CSRF漏洞与SSRF漏洞的主要区别在于伪造目标的不同。 一、SSRF是什么 SSRF漏洞&#xff1a;&#xff08;Server-Side Request Forgery&#xff0c;服务器端请求伪造&#xff09;是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下&#xff0c;SSRF攻击的目标是从…

【MySQL】范式 (十五)

&#x1f697;MySQL学习第十五站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ ⭐学习汇总贴&#xff0c;超详细思维导图&#xff1a;【MySQL】学习汇总(完整思维导图) 一.引入 在关系型数据库中&#xf…

浅谈AI浪潮下的视频大数据发展趋势与应用

视频大数据的发展趋势是多样化和个性化的。随着科技的不断进步&#xff0c;人们对于视频内容的需求也在不断变化。从传统的电视节目到现在的短视频、直播、VR等多种形式&#xff0c;视频内容已经不再是单一的娱乐方式&#xff0c;更是涉及到教育、医疗、商业等各个领域。 为了满…

一、初识 Spring MVC

文章目录 一、初始 Spring MVC1.1 回顾 MVC 模式1.2 回顾 Servlet 一、初始 Spring MVC 什么是 Spring MVC Spring MVC就是一个 Spring 内置的 MVC 框架。 MVC框架&#xff0c;它解决WEB开发中常见的问题(参数接收、文件上传、表单验证、国际化等等)&#xff0c;而且使用…

Stable Diffusion - 俯视 (from below) 拍摄的人物图像 LoRA 与配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132192139 图像来自 哥特风格 LoRA 俯视 LoRA&#xff0c;提升视觉冲击力&#xff0c;核心配置 <lora:view_from_below:0.6>,(from below,…

Linux6.36 Kubernetes Pod进阶

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes Pod进阶一、资源限制1.CPU 资源单位2.内存 资源单位3.重启策略&#xff08;restartPolicy&#xff09;4.健康检查&#xff1a;又称为探针&#xff08;Probe&#xff09;5.启动、退出动作 计算机系统 5G云计算 第三章 LIN…

WMS系列:层级树的surface 的创建

WMS 创建的surface 与 surfaceflinger 创建的Layer 是一一对应的&#xff0c;只不过可能是创建不同的 Layer 1. DefaultTaskDisplayArea 对应的surface 的创建 DefaultTaskDisplayArea 的调用栈如下&#xff0c;是在系统进程启动服务的时候&#xff0c;去创建对应的SurfaceCont…

研发提测前测试到底能做些什么

目录 需求分析 研发设计分析 测试用例编写 接口文档测试 内部业务逻辑 数据库测试 jimdb测试 异常流程测试 总结 作为测试&#xff0c;经常会遇到倒排期的项目&#xff0c;当研发已经占用了很多资源的情况下&#xff0c;此时测试要想提高效率。就不得不在研发提测前多做…

【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio构建SpringSecurity权限框架

1.Cloud Studio&#xff08;云端 IDE&#xff09;简介 Cloud Studio 是基于浏览器的集成式开发环境&#xff08;IDE&#xff09;&#xff0c;为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装&#xff0c;随时随地打开浏览器就能在线编程。 Clou…

Towards Open World Object Detection【论文解析】

Towards Open World Object Detection 摘要1 介绍2 相关研究3 开放世界目标检测4 ORE:开放世界目标检测器4.1 对比聚类4.2 RPN自动标注未知类别4.3 基于能量的未知标识4.4 减少遗忘 5 实验5.1开放世界评估协议5.2 实现细节5.3 开放世界目标检测结果5.4 增量目标检测结果 6 讨论…

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据 1、时间&#xff1a;2000-2021年 2、来源&#xff1a;国家知识产权局 3、范围&#xff1a;地级市&#xff08;具体每年地级市数量参看下文图片&#xff09; 4、指标&#xff1a;申请专利数&…

吐血整理,Python接口自动化测试-接口关联依赖处理(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 场景说明 在面试…

【TypeScript】类型断言-类型的声明和转换(五)

【TypeScript】类型断言-类型的声明和转换&#xff08;五&#xff09; 【TypeScript】类型断言-类型的声明和转换&#xff08;五&#xff09;一、简介二、断言形式2.1 尖括号语法2.2 as形式 三、断言类型3.1 非空断言3.2 肯定断言-肯定化保证赋值3.3 将任何类型断言为any3.4 调…

【STL】优先级队列反向迭代器详解

目录 一&#xff0c;栈_刷题必备 二&#xff0c;stack实现 1.什么是容器适配器 2.STL标准库中stack和queue的底层结构 了解补充&#xff1a;容器——deque 1. deque的缺陷 2. 为什么选择deque作为stack和queue的底层默认容器 三&#xff0c;queue实现 1. 普通queue …