当前位置: 首页 > news >正文

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

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

运行结果如下:

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

相关文章:

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

目录 1、Bridge模式的提出 2、Bridge模式的定义 3、Bridge模式总结 4、需求描述 5、多继承方式实现 6、使用Bridge设计模式实现 1、Bridge模式的提出 在软件功能模块设计中&#xff0c;如果类的实现功能划分不清晰&#xff0c;使得继承得到的子类往往是随着需求的变化&am…...

springboot异步任务

在Service类声明一个注解Async作为异步方法的标识 package com.qf.sping09test.service;import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service;Service public class AsyncService {//告诉spring这是一个异步的方法Asyncp…...

Flutter父宽度自适应子控件的宽度

需求&#xff1a; 控件随着金币进行自适应宽度 image.png 步骤&#xff1a; 1、Container不设置宽度&#xff0c;需要设置约束padding&#xff1b; 2、文本使用Flexible形式&#xff1b; Container(height: 24.dp,padding: EdgeInsetsDirectional.only(start: 8.dp, end: 5.d…...

什么是 API 安全?学习如何防止攻击和保护数据

随着 API 技术的普及&#xff0c;API 安全成为了一个越来越重要的问题。本文将介绍什么是 API 安全&#xff0c;以及目前 API 面临的安全问题和相应的解决方案。 什么是 API 安全 API 安全是指保护 API 免受恶意攻击和滥用的安全措施。API 安全通常包括以下几个方面&#xff1…...

简述 TCP 和 UDP 的区别以及优缺点和使用场景?

一、TCP与UDP区别总结&#xff1a; 1、TCP面向连接&#xff08;如打电话要先拨号建立连接&#xff09;;UDP是无连接的&#xff0c;即发送数据之前不需要建立连接 2、TCP提供可靠的服务。也就是说&#xff0c;通过TCP连接传送的数据&#xff0c;无差错&#xff0c;不丢失&…...

react进阶

react-virtualized的高阶组件&#xff0c;Autosize可以使屏幕适配。使用render-props模式来获取到AutoSizer组件暴露的width和height属性。JSON.parse(JSON.stringify())不适用于有undefined的数据。 深拷贝的使用&#xff0c;不能使用在有undefined的数据中。有直接过滤undefi…...

使用windows搭建WebDAV服务,并内网穿透公网访问【无公网IP】

文章目录 1. 安装IIS必要WebDav组件2. 客户端测试3. 使用cpolar内网穿透&#xff0c;将WebDav服务暴露在公网3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功 1. Linux(centos8…...

科技感响应式管理系统后台登录页ui设计html模板

做了一个科技感的后台管理系统登录页设计&#xff0c;并且尝试用响应式布局把前端html写了出来&#xff0c;发现并没有现象中的那么容易&#xff0c;chrome等标准浏览器都显示的挺好&#xff0c;但IE11下面却出现了很多错位&#xff0c;兼容起来还是挺费劲的&#xff0c;真心不…...

Lombok的使用及注解含义

文章目录 一、简介二、如何使用2.1、在IDEA中安装Lombok插件2.2、添加maven依赖 三、常用注解3.1、Getter / Setter3.2、ToString3.3、NoArgsConstructor / AllArgsConstructor3.4、EqualsAndHashCode3.5、Data3.6、Value3.7、Accessors3.7.1、Accessors(chain true)3.7.2、Ac…...

实时通信应用的开发:Vue.js、Spring Boot 和 WebSocket 整合实践

目录 1. 什么是webSocket 2. webSocket可以用来做什么? 3. webSocket协议 4. 服务器端 5. 客户端 6. 测试通讯 1. 什么是webSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务…...

【C++】C++异常

文章目录 1. C语言传统处理错误的方式2. C异常的概念3. 异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 4. C标准库的异常体系5. 自定义的异常体系6. 异常的优缺点 1. C语言传统处理错误的方式 C语言传统的错误处理机制有两个&#xff1a; 终止程…...

学生成绩管理系统V2.0

某班有最多不超过30人&#xff08;具体人数由键盘输入&#xff09;参加某门课程的考试&#xff0c;参考前面章节的“学生成绩管理系统V1.0”&#xff0c;用一维数组和函数指针作函数参数编程实现如下菜单驱动的学生成绩管理系统&#xff0c;其中每位同学的学号和成绩等数据可以…...

【C++】开源:tinyxml2解析库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍tinyxml2解析库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…...

如何使用webpack打包一个库library,使用webpack打包sdk.

如何使用webpack打包一个库library 如果你需要自己封装一些包给别人使用,那么可以参考以下方法 初始化库 mkdir library cd library npm init -y经过以上步骤后会生成一个library文件夹&#xff0c;里面包含一个package.json文件。然后简单修改为如下所示&#xff1a; {&qu…...

项目一:基于stm32的阿里云智慧消防监控系统

若该文为原创文章&#xff0c;转载请注明原文出处。 Hi&#xff0c;大家好&#xff0c;我是忆枫&#xff0c;今天向大家介绍一个单片机项目。 一、简介 智慧消防监控系统&#xff0c;是用于检测火灾&#xff0c;温度&#xff0c;烟雾的监控系统。以 stm32单片机为核心外加 MQ…...

【果树农药喷洒机器人】Part6:基于深度相机与分割掩膜的果树冠层体积探测方法

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…...

打印1到最大的n位数

目录 1.题目概述 2.题解 1.题目概述 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 1. 用返回一个整数列表来代替打印 2. n 为正整数&#xff0c;0 < n < 5 示例&#xff1a; 输入…...

设计模式行为型——状态模式

目录 状态模式的定义 状态模式的实现 状态模式角色 状态模式类图 状态模式举例 状态模式代码实现 状态模式的特点 优点 缺点 使用场景 注意事项 实际应用 在软件开发过程中&#xff0c;应用程序中的部分对象可能会根据不同的情况做出不同的行为&#xff0c;把这种对…...

ElastAlert通过飞书机器人发送报警通知

前言 公司采用ELK架构搜集业务系统的运行日志&#xff0c;以前开发人员只有在业务出现问题的时候&#xff0c;才会去kibana上进行日志搜索操作&#xff0c;每次都是被用户告知系统出问题了&#xff0c;这简直是被啪啪打脸~ 于是痛定思痛&#xff0c;决定主动出击&#xff0c;…...

恒温碗语音芯片,具备数码管驱动与温度传感算法,WT2003H-B012

近年来&#xff0c;随着科技的飞速发展&#xff0c;智能家居产品已然成为了现代生活的一部分&#xff0c;为人们的生活带来了更多的便利和舒适。在这个不断演进的领域中&#xff0c;恒温碗多功能语音芯片——WT2003H-B012成为众多厂商的首选&#xff0c;为智能家居领域注入了全…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!

今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等&#xff0c;设置经线、纬线都以10间隔显示。 2、需要插入背会归线&#xf…...

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址&#xff0c;您可以使用以下几种方法&#xff1a; 1. 查看所有远程仓库地址 使用 git remote -v 命令&#xff0c;它会显示项目中配置的所有远程仓库及其对应的 URL&#xff1a; git remote -v输出示例&#xff1a; origin https://…...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...

AT模式下的全局锁冲突如何解决?

一、全局锁冲突解决方案 1. 业务层重试机制&#xff08;推荐方案&#xff09; Service public class OrderService {GlobalTransactionalRetryable(maxAttempts 3, backoff Backoff(delay 100))public void createOrder(OrderDTO order) {// 库存扣减&#xff08;自动加全…...

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...

【前端实战】如何让用户回到上次阅读的位置?

目录 【前端实战】如何让用户回到上次阅读的位置&#xff1f; 一、总体思路 1、核心目标 2、涉及到的技术 二、实现方案详解 1、基础方法&#xff1a;监听滚动&#xff0c;记录 scrollTop&#xff08;不推荐&#xff09; 2、Intersection Observer 插入探针元素 3、基…...