【19】c++设计模式——>桥接模式

桥接模式的定义

C++的桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使得它们可以独立地变化。桥接模式的核心思想是利用组合关系代替继承关系,将系统划分成多个独立的、功能不同的类层次结构,并通过桥接类将它们连接起来。
在桥接模式中,有两个重要的概念:抽象化(Abstraction)和实现化(Implementation),它们分别对应了系统的抽象部分和实现部分。抽象化负责定义接口,并维护一个指向实现化对象的指针;实现化则负责定义具体的实现方法。

使用场景

关于桥接模式的使用对应的场景有很多,比如:
1.空调、电视等和他们对应的遥控器:空调、电视机是抽象,遥控器是实现;
2.手机品牌和手机软件:手机品牌是抽象,手机软件是实现;
3.跨品台的GUI在不同平台上运行:程序的GUI层是抽象,操作系统API是实现。
4.假设我们正在开发一个图形绘制应用程序,支持多种图形和不同的绘制渲染方式。其中,图形包括圆形、矩形等,渲染方式包括使用直线绘制、使用虚线绘制等。这两个维度的变化都可能会在未来进行扩展和修改。
就是说将具体的图形和具体的渲染桥接在一起,实现图形和渲染方式之间的解耦,我们可以在客户端代码中使用桥接模式,通过实例化具体的图形对象和具体的渲染实现对象,将它们桥接在一起,并进行绘制:

#include <iostream>// Abstract Render API
class RenderAPI {
public:virtual void renderCircle() = 0;         // 抽象的渲染圆形方法virtual void renderRectangle() = 0;      // 抽象的渲染矩形方法
};// Concrete Line Renderer
class LineRenderer : public RenderAPI {
public:void renderCircle() override {std::cout << "Render Circle with lines." << std::endl;     // 使用线条渲染圆形}void renderRectangle() override {std::cout << "Render Rectangle with lines." << std::endl;  // 使用线条渲染矩形}
};// Concrete Dashed Line Renderer
class DashedLineRenderer : public RenderAPI {
public:void renderCircle() override {std::cout << "Render Circle with dashed lines." << std::endl;    // 使用虚线渲染圆形}void renderRectangle() override {std::cout << "Render Rectangle with dashed lines." << std::endl; // 使用虚线渲染矩形}
};// Abstract Shape
class Shape {
protected:RenderAPI* renderAPI;public:Shape(RenderAPI* api) : renderAPI(api) {}virtual void draw() = 0;   // 抽象的绘制方法,具体的形状类将实现这个方法
};// Concrete Circle
class Circle : public Shape {
public:Circle(RenderAPI* api) : Shape(api) {}void draw() override {renderAPI->renderCircle();   // 调用渲染API的渲染圆形方法来绘制圆形}
};// Concrete Rectangle
class Rectangle : public Shape {
public:Rectangle(RenderAPI* api) : Shape(api) {}void draw() override {renderAPI->renderRectangle();   // 调用渲染API的渲染矩形方法来绘制矩形}
};int main() {// 创建一个圆形对象,并设置使用线条渲染的渲染APIShape* circleShape = new Circle(new LineRenderer());// 创建一个矩形对象,并设置使用虚线渲染的渲染APIShape* rectangleShape = new Rectangle(new DashedLineRenderer());// 绘制圆形circleShape->draw();// 绘制矩形rectangleShape->draw();delete circleShape;delete rectangleShape;return 0;
}

海贼王实例

对于海贼王中来说,有海军,有海贼团,不论是海军还是海贼团,他们都有自己的船,海军的船叫军舰,海贼团的船叫海贼船,因此,我们需要将船和团队分开;
船+海贼团 -->海贼船
船+海军—>军舰
对于一个海贼团或者一支海军部队来说,光有船是不完整的,船只是这个团队的抽象,如果想要让它鲜活起来就必要要有由人组成的团队,也就是抽象的具体实现。所以,在这个抽象类中包含了一个团队对象,船和团队二者之间的关系可以看做是聚合关系。
我们以草帽海贼团和斯摩格海贼团为例:

#include <iostream>
#include<string>
#include<map>
using namespace std;//不论是哪艘船上的船员肯定都是由一些个人的身份信息,为了将这些信息记录下来,先定一个存储数据的类:
//人员信息
struct Person
{Person(string name, string job, string ability, string reward, string beizhu=string()){this->name = name;this->job = job;this->ability = ability;this->reward = reward;this->beizhu = beizhu;}~Person(){cout << name << "被析构了..." << endl;}string name;     //姓名string job;      //工作string ability;  //能力string reward;   //赏金string beizhu;   //备注
};
//关于团队的成员组成可以是海贼,也可以是海军,所以先定义一个团队的抽象类
class AbstractTeam
{
public:AbstractTeam(string name):m_teamName(name) {}//获取团队姓名string getTeamName(){return m_teamName;}//给团队添加成员,用map保存,键是姓名,值是Person类void addMember(Person* p){m_infoMap.insert(make_pair(p->name,p));}//打印成员信息void show(){cout << m_teamName << ":" << endl;//遍历mapfor(const auto & item:m_infoMap){cout << "【Name: " << item.second->name<< ", Job: " << item.second->job<< ", Ability: " << item.second->ability<< ", MoneyReward: " << item.second->reward<< ", BeiZhu: " << item.second->beizhu<< "】" << endl;}}//执行任务函数,海军和海贼的任务不同,因此是纯虚函数,子类中重写virtual void executeTask() = 0;//虚析构函数,释放类时,将m_infoMap保存的团队所有成员都析构掉virtual ~AbstractTeam(){for (const auto& item : m_infoMap){delete item.second;}}
protected:string m_teamName = string();//该团队的所有成员map<string, Person*> m_infoMap;
};
//具体的团队类,路飞的草帽海贼团和斯摩格的海军团
//草帽海贼团
class CaoMaoTeam :public AbstractTeam
{
public:using AbstractTeam::AbstractTeam;//继承基类的构造函数,而不用子类重新实现相同的构造函数void executeTask() override{cout << "在海上冒险,找到 ONE PIECE 成为海贼王!" << endl;}
};
//斯摩格海军团队
class SmokeTeam :public AbstractTeam
{
public:using AbstractTeam::AbstractTeam;void executeTask()override{cout << "为了正义,先将草帽一伙一网打尽!!!" << endl;}
};
//船类
/*不论是海军还是海贼在大海上航行都需要船,虽然他们驾驶的船只不同,
但是有很多属性还是一致的,所以我们可以先定义一个船的抽象类*/
class AbstructShip
{
public:AbstructShip(AbstractTeam* team) :m_team(team) {} //团队+船void showTeam(){m_team->show();m_team->executeTask();}virtual string getName() = 0;virtual void feature() = 0; //纯虚函数描述船的特点,在不同的子类中都需要重写virtual~AbstructShip() {}
protected:AbstractTeam* m_team = nullptr; //这里将团队和船绑定在一起了
};
//梅丽号
class Merry :public AbstructShip
{
public:using AbstructShip::AbstructShip;string getName() override{return string("前进梅丽号");}void feature()override{cout << getName() << "--船首为羊头,在司法岛化身船精灵舍己救下草帽一伙" << endl;}
};
//海军无敌战舰
class HaiJunJian :public AbstructShip
{
public:using AbstructShip::AbstructShip;string getName()override{return string("无敌海军号");}void feature() override{cout << getName() << " -- 船底由海楼石建造, 可以穿过无风带的巨大炮舰!" << endl;}
};
int main()
{//草帽海贼团CaoMaoTeam* caomao = new CaoMaoTeam("草帽海贼团");Person* luffy = new Person("路飞", "船长", "橡胶果实能力者", "30亿贝里", "爱吃肉");Person* zoro = new Person("索隆", "剑士", "三刀流", "11亿1100万贝里", "路痴");Person* sanji = new Person("山治", "厨师", "隐形黑", "10亿3200万贝里", "好色");Person* nami = new Person("娜美", "航海士", "天候棒+宙斯", "3亿6600万贝里", "喜欢钱");caomao->addMember(luffy);caomao->addMember(zoro);caomao->addMember(sanji);caomao->addMember(nami);Merry* sunny = new Merry(caomao);sunny->feature();sunny->showTeam();//斯摩格SmokeTeam* smoke =  new SmokeTeam("斯摩格海军团");Person* smoker = new Person("斯摩格", "中将", "冒烟果实能力者", "", "爱吃烟熏鸡肉");Person* dasiqi = new Person("达斯琪", "大佐", "一刀流", "", "近视");smoke->addMember(smoker);smoke->addMember(dasiqi);HaiJunJian* ship = new HaiJunJian(smoke);ship->feature();ship->showTeam();delete caomao;delete sunny;delete smoke;delete ship;return 0;}

在这里插入图片描述

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

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

相关文章

Suricata + Wireshark离线流量日志分析

目录 一、访问一个404网址&#xff0c;触发监控规则 1、使用python搭建一个虚拟访问网址 2、打开Wireshark,抓取流量监控 3、在Suricata分析数据包 流量分析经典题型 入门题型 题目&#xff1a;Cephalopod(图片提取) 进阶题型 题目&#xff1a;抓到一只苍蝇(数据包筛选…

c语言练习题83:#include“ “和#include<>的区别

#include" "和#include<>的区别 #include<> 默认根据环境变量的值去先搜索标准库&#xff0c;搜索系统文件会比较快。 #include“” 先搜索当前工程的路径&#xff0c;搜索自己自定义的文件会比较快。 因此自定义的头文件的名称包含在<>中的话…

【Docker】Docker的工具实践及root概念,时间戳的概念和Docker容器安全性设置的详细讲解

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

运行软件提示丢失msvcr120.dll文件怎么办?msvcr120.dll丢失的5个最新解决方法

找不到msvcr120.dll是一个常见的错误信息&#xff0c;通常会在用户尝试运行某些程序或游戏时出现。msvcr120.dll是 Windows 操作系统中的一个动态链接库文件&#xff0c;它包含了 C 运行时库的一些函数和类&#xff0c;对于许多程序和游戏的正常运行至关重要。 当用户遇到找不到…

POI 和 EasyExcel 操作 Excel

一、概述 目前操作 Excel 比较流行的就是 Apache POI 和阿里巴巴的 easyExcel。 1.1 POI 简介 Apache POI 是用 Java 编写的免费开源的跨平台的 Java API&#xff0c;Apache POI 提供 API 给 Java 程序对 Microsoft Office 格式文档读和写的常用功能。POI 为 “Poor Obfuscati…

一般香港服务器带宽选多大够用?(带宽计算方法)

​  在海外IDC市场份额中&#xff0c;香港服务器依托自身优越的服务器资源条件&#xff0c;在各个行业中发挥的重要作用。但是&#xff0c;不同业务对网络带宽的要求各不相同&#xff0c;弄清楚如何计算带宽需求对于确保业务平稳运行至关重要&#xff0c;最好从一开始就使用正…

039:mapboxGL更换地图上的鼠标样式

第039个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中更换地图上的鼠标的样式。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共74行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:htt…

012-第二代硬件选型

第二代硬件选型 文章目录 第二代硬件选型项目介绍重新换平台缘由X86 && Arm 架构切换 ARM Linux 硬件选型系统确定Qt 版本确定总结一下 关键字&#xff1a; Qt、 Qml、 Arm、 X86、 linux 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QM…

【jvm--方法区】

文章目录 1. 栈、堆、方法区的交互关系2. 方法区的内部结构3. 运行时常量池4. 方法区的演进细节5. 方法区的垃圾回收 1. 栈、堆、方法区的交互关系 方法区的基本理解&#xff1a; 方法区&#xff08;Method Area&#xff09;与 Java 堆一样&#xff0c;是各个线程共享的内存区…

4.MySql安装配置(更新版)

MySql安装配置 无论计算机是否有安装其他mysql&#xff0c;都不要卸载。 只要确定大版本是8即可&#xff0c;8.0.33 8.0.34 差别不大即可。 MySql下载安装适合电脑配置属性有关&#xff0c;一次性安装成功当然是非常好的&#xff0c;因为卸载步骤是非常麻烦的 如果第一次安装…

医疗器械标准目录汇编2022版共178页(文中附下载链接!)

为便于更好地应用医疗器械标准&#xff0c;国家药监局医疗器械标准管理中心组织对现行1851项医疗器械国家和行业标准按技术领域&#xff0c;编排形成《医疗器械标准目录汇编&#xff08;2022版&#xff09;》 该目录汇编分为通用技术领域和专业技术领域两大类&#xff0c;通用…

NoSQL Redis

NoSQL Redis 1、数据库1.1关系型数据库1.2非关系型数据库1.3关系型和非关系型区别 2、非关系型数据库应用场景3、存储结构4、redis4.1redis概述4.2Redis 优点4.3Redis为什么这么快&#xff1f; 5、部署redis6、redis基础操作 1、数据库 1.1关系型数据库 关系型数据库是一个结…

机械臂抓取的产业落地进展与思考

工业机械臂是一种能够模拟人类手臂动作的机械装置&#xff0c;具有高精度、高速度和高灵活性的特点。近年来&#xff0c;随着人工智能和机器人技术的快速发展&#xff0c;机械臂在工业生产、物流仓储、医疗护理等领域得到了广泛应用。机械臂抓取技术作为机械臂的核心功能之一&a…

UniAD 论文学习

一、解决了什么问题&#xff1f; 当前的自动驾驶方案大致由感知&#xff08;检测、跟踪、建图&#xff09;、预测&#xff08;motion、occupancy&#xff09;和规划三个模块构成。 为了实现各种功能&#xff0c;智驾方案大致包括两种路线。一种是针对每个任务都部署一个模型&a…

Python Parser 因子计算性能简单测试

一直以来&#xff0c;Python 都在量化金融领域扮演着至关重要的角色。得益于 Python 强大的库和工具&#xff0c;用户在处理金融数据、进行数学建模和机器学习时变得更加便捷。但作为一种解释性语言&#xff0c;相对较慢的执行速度也限制了 Python 在一些需要即时响应的场景中的…

知识图谱系列3:读论文-《中国鸟类领域知识图谱构建与应用研究》-面向知识图谱的智能服务研究(需求、管理、查询、推理)

5.1鸟类领域知识服务需求研究 本部分根据不同人群&#xff0c;对其需求进行了研究。 并总结需求类型如下。 知识型服务需求指用户学习鸟类相关知识&#xff0c;包括知识内容、知识学习等。知识内容 需求为构建鸟类领域知识库作为知识的来源&#xff1b;知识学习需求为用户通过…

gici-open示例数据运行(ground_truth坐标的转换)

1. 坐标系转换说明 涉及的两个坐标转换&#xff1a; nmea_pose_to_pose &#xff1a;激光IMU中心到数据集IMU中心&#xff0c;主要是杆臂误差&#xff0c;转换关系为&#xff1a; //坐标转换的主要步骤(若发现有错误的地方&#xff0c;请评论指出) //定义激光IMU和数据集IMU之…

好看的机制示意图绘制教程汇总

好看的机制示意图绘制教程汇总 蛋白翻译过程示意图&#xff0c;特别是其中的核糖体&#xff0c;需要很多绘制技巧。主要使用椭圆工具绘制两个椭圆&#xff0c;二者组合后使外形接近核糖体。接着通过路径查找器的合并功能&#xff08;并集&#xff09;将两个椭圆合并在一起。使…

使用HHDBCS管理MongoDB

1 连接MongoDB 打开HHDBCS&#xff0c;在数据库类型中选择mongodb&#xff0c;填入相关信息&#xff0c;点击“登陆”即可。 也可以使用SSH通道进行登陆。 2 命令窗口 点击命令窗口&#xff0c;可以对数据库发出指令。 可以根据个人习惯&#xff0c;对命令窗口进行设置…

矩阵的相似性度量的常用方法

矩阵的相似性度量的常用方法 1&#xff0c;欧氏距离 欧式距离是最易于理解的一种距离计算方法&#xff0c;源自欧式空间中两点间的距离公式。 (1)二维平面上的点 a ( x 1 , y 1 ) a(x_1,y_1) a(x1​,y1​)和点 b ( x 2 , y 2 ) b(x_2,y_2) b(x2​,y2​)的欧式距离为 d ( x …