设计模式之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;
}

运行结果如下:

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于 Eclipse 的一场 “三角关系”

上个世纪 90 年代&#xff0c;世界上的计算机要么不联网&#xff0c;要么在企业内部联网。但是&#xff0c;在互联网的概念下&#xff0c;计算机之间共享信息和资源的需求成为了必要。 1995 年 5 月&#xff0c;Java 横空出世。Java 的父亲是当时凭借 Solaris 操作系统风头正盛…

flutter 手写日历组件

先看效果 直接上代码 calendar_popup_view.dart import package:flutter/material.dart; import package:intl/intl.dart;import custom_calendar.dart; import hotel_app_theme.dart;class CalendarPopupView extends StatefulWidget {const CalendarPopupView({required th…

OpenCV项目开发实战--相机校准—并附实例Python/C++代码实现

介绍 相机标定是计算机视觉中的一项基本任务在 3D 重建、对象跟踪、增强现实和图像分析等各种应用中至关重要。准确的校准通过校正失真和估计相机的内在和外在参数来确保精确的测量和可靠的分析。这本综合指南深入探讨了相机校准的原理、技术和算法。我们探索获取相机的内在和…

macOS使用ffmpeg与QT进行音视频推拉流

1.先启动流服务器 ./mediamtx 2.开始推流: ffmpeg -re -stream_loop -1 -i /Users/hackerx/Desktop/test.mp4 -c copy -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream 3. 安装ffmpeg 4.4 brew install ffmpeg4 4.添加ffmpeg头文件目录与库目录 5.链接ffmpeg相关库…

Flink窗口分类简介及示例代码

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 1. 流式计算2. 窗口3. 窗口的分类◆ 基于时间的窗口&#xff08;时间驱动&#xff09;1) 滚动窗口&#xff08;Tumbling Windows&#xff09;2) 滑动窗口&#xff08;Sliding Windows&…

Axure RP移动端高保真CRM办公客户管理系统原型模板及元件库

Axure RP移动端高保真CRM办公客户管理系统原型模板及元件库&#xff0c;一套典型的移动端办公工具型APP Axure RP原型模板&#xff0c;可根据实际的产品需求进行扩展&#xff0c;也可以作为移动端原型设计的参考案例。为提升本作品参考价值&#xff0c;在模板设计过程中尽量追求…

VVIC-据关键词取商品列表

一、接口参数说明&#xff1a; item_search-根据关键词取商品列表&#xff0c;点击更多API调试&#xff0c;请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/vvic/item_search 名称类型必须描述keyString是调用key&#xff08;点击…

c++中的多态

文章目录 1.多态的概念1.1概念 2.多态的定义及实现2.1多态的构成条件2.2虚函数2.3虚函数的重写2.4 C11 override 和 final2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 抽象类3.1概念3.2接口继承和实现继承 4.多态的原理4.1虚函数表4.2多态原理分析4.3 动态绑定与静态绑定 5.单…

仿到位|独立版家政上门预约服务小程序家政保洁师傅上门服务小程序上门服务在线派单源码

上门预约服务派单小程序家政 小程序 同城预约 开源代码 独立版. 程序完整,经过安装检测,可放心下载安装。 适合本地的一款上门预约服务小程序,功能丰富,适用多种场景。 程序功能:城市管理/小程序DIY/服务订单/师傅管理/会员卡功能/营销功能/文章功能等等

【深度学习 video detect】Towards High Performance Video Object Detection for Mobiles

文章目录 摘要IntroductionRevisiting Video Object Detection BaselinePractice for Mobiles Model Architecture for MobilesLight Flow 摘要 尽管在桌面GPU上取得了视频目标检测的最近成功&#xff0c;但其架构对于移动设备来说仍然过于沉重。目前尚不清楚在非常有限的计算…

【人工智能前沿弄潮】——生成式AI系列:Diffusers应用 (2) 训练扩散模型(无条件图像生成)

无条件图像生成是扩散模型的一种流行应用&#xff0c;它生成的图像看起来像用于训练的数据集中的图像。与文本或图像到图像模型不同&#xff0c;无条件图像生成不依赖于任何文本或图像。它只生成与其训练数据分布相似的图像。通常&#xff0c;通过在特定数据集上微调预训练模型…

jxls导出问题

![请添加图片描述](https://img-blog.csdnimg.cn/bc74c4207818491c93b75e19b3333451.png 为什么最后导出的文件还是按原样导出啊&#xff0c;没有填充数据 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d4500b9a98c042f6b64a5d0650071303.png

云安全攻防(八)之 Docker Remote API 未授权访问逃逸

Docker Remote API 未授权访问逃逸 基础知识 Docker Remote API 是一个取代远程命令行界面&#xff08;rcli&#xff09;的REST API&#xff0c;其默认绑定2375端口&#xff0c;如管理员对其配置不当可导致未授权访问漏洞。攻击者利用 docker client 或者 http 直接请求就可以…

【PostgreSQL的CLOG解析】

同样还是这张图&#xff0c;之前发过shared_buffer和os cache、wal buffer和work mem的文章&#xff0c;今天的主题是图中的clog&#xff0c;即 commit log&#xff0c;PostgreSQL10之前放在数据库目录的pg_clog下面。PostgreSQL10之后修更名为xact,数据目录变更为pg_xact下面&…

Vue+SpringBoot项目开发:登录页面美化,登录功能实现(三)

写在开始:一个搬砖程序员的随缘记录上一章写了从零开始VueSpringBoot后台管理系统&#xff1a;Vue3TypeScript项目搭建 VueTypeScript的前端项目已经搭建完成了 这一章的内容是引入element-plus和axios实现页面的布局和前后端数据的串联&#xff0c;实现一个登陆的功能&#x…

CSS变形与动画(一):transform变形 与 transition过渡动画 详解(用法 + 代码 + 例子 + 效果)

文章目录 变形与动画transform 变形translate 位移scale 缩放rotate 旋转skew 倾斜多种变形设置变形中心点 transition 过渡动画多种属性变化 变形与动画 transform 变形 包括&#xff1a;位移、旋转、缩放、倾斜。 下面的方法都是transform里的&#xff0c;记得加上。 展示效…

Apache Maven:从构建到部署,一站式解决方案

目录 一、Maven介绍 1. Maven是什么&#xff1f; 2.Maven的作用&#xff1f; 二、Maven仓库介绍 2.1 库的分类 三、Maven安装与配置 3.1 Maven安装 3.2 Maven环境配置 3.3 仓库配置 四、Eclipse与Maven配置 五、Maven项目测试 5.1 新建Maven项目步骤及注意事项 5.…

C/C++test两步完成CMake项目静态分析

您可能一直在静态分析中使用CMake。但您是否尝试过将Parasoft C/Ctest与CMake一起使用吗&#xff1f;以下是如何使用C/Ctest在基于CMake的项目中运行静态分析的详细说明。 CMake是用于构建、测试和打包软件的最流行的工具之一。Parasoft C/Ctest通过简化构建管理过程&#xff…

RabbitMQ基础(2)——发布订阅/fanout模式 topic模式 rabbitmq回调确认 延迟队列(死信)设计

目录 引出点对点(simple)Work queues 一对多发布订阅/fanout模式以登陆验证码为例pom文件导包application.yml文件rabbitmq的配置生产者生成验证码&#xff0c;发送给交换机消费者消费验证码 topic模式配置类增加配置生产者发送信息进行发送控制台查看 rabbitmq回调确认配置类验…

Redis_缓存1_缓存类型

14.redis缓存 14.1简介 穿透型缓存&#xff1a; 缓存与后端数据交互在一起&#xff0c;对服务端的调用隐藏细节。如果从缓存中可以读到数据&#xff0c;就直接返回&#xff0c;如果读不到&#xff0c;就到数据库中去读取&#xff0c;从数据库中读到数据&#xff0c;也是先更…