C++ 【桥接模式】

简单介绍

桥接模式属于 结构型模式 | 可将一个大类或一系列紧密相关的类拆分 为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。

聚合关系:两个类处于不同的层次,强调了一个整体/局部的关系,当汽车对象销毁时,轮胎对象也可以单独存在

public class 轮胎{  }
public class 汽车{protected:轮胎 tyre[4];
}

基础理解

Q:为什么要用桥接模式
A:使得抽象部分和实现部分分离,使它们可以独立地变化。且允许抽象部分和实现部分之间建立多对多的关系形成 聚合关系

Q:什么是抽象什么是实现
A:抽象 是一些实体的高阶控制层。抽象调用实现,实现来完成具体实现的工作

这里的形状就是抽象,与涂颜色(实现)形成聚合关系:抽象包含涂颜色
在这里插入图片描述

UML 图

解释:客户端只需要调用抽象部分。抽象部分与实现部分成为聚合关系。你可以详写一个精确的抽象,然后就可以在客户端用这个精确的抽象调用具体的实现。


空心箭头:继承关系
实线箭头:关联关系
棱形实线箭头:聚合关系
在这里插入图片描述

抽象部分和实现部分

在实际的程序中, 你可以在两个独立方向上扩展这种应用:

开发多个不同的 精确抽象 (例如:面向微信用户和支付宝用户 )
支持多个不同的 具体实现 (例如:能够使用 密码支付 人脸支付 和 指纹支付)。

  1. 抽象对象控制程序的外观
    (微信用户和支付宝用户抽象成用户,通过这些抽象对象,我们可以统一对支付进行管理和调用,而不需要关心具体的支付实现方式。)
  2. 并将真实工作委派给连入的实现对象
    (抽象类与实现类发生聚合关系,抽象类可以调用密码支付 人脸支付 和 指纹支付方式)
  3. 不同的实现只要遵循相同的接口就可以互换
    (只要遵循了相同的接口:PaymentMode 支付接口,就可以在程序中互换使用)
  4. 精确抽象(微信用户)就可以使用多个具体实现接口( 密码支付 人脸支付 和 指纹支付)

关键点:聚合关系,精确抽象类构造函数中对不同API 的调用

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;// 支付方式接口
class PaymentMode
{
public:virtual ~PaymentMode() {}virtual bool security(string uId) = 0;
};// 具体支付方式实现类:密码支付
class PayByCypher : public PaymentMode
{
public:bool security(string uId) override{cout << "密码支付的安全检查" << endl;// 实现具体的安全验证逻辑return true;
}
}
;// 具体支付方式实现类:人脸支付
class PayByFace : public PaymentMode
{
public:bool security(string uId) override{cout << "人脸支付的安全检查" << endl;// 实现具体的安全验证逻辑return true;}
};// 具体支付方式实现类:指纹支付
class PayByFingerprint : public PaymentMode
{
public:bool security(string uId) override{cout << "指纹支付的安全检查" << endl;// 实现具体的安全验证逻辑return true;}
};// 支付抽象类
class Payment
{
public:Payment(PaymentMode *mode_) : mode(mode_) {}virtual ~Payment() {}virtual void pay(string uId, string tradeId, long long amount) = 0;protected:PaymentMode *mode;
};// 扩展抽象化角色:微信支付
class WxPayment : public Payment
{
public:WxPayment(PaymentMode *mode) : Payment(mode) {}void pay(string uId, string tradeId, long long amount) override{cout << "使用微信支付" << endl;bool isSecure = mode->security(uId);if (isSecure){cout << "微信支付成功,交易号:" << tradeId << ",金额:" << amount << endl;}else{cout << "微信支付失败,交易号:" << tradeId << ",金额:" << amount << endl;}}
};// 扩展抽象化角色:支付宝支付
class AliPayment : public Payment
{
public:AliPayment(PaymentMode *mode) : Payment(mode) {}void pay(string uId, string tradeId, long long amount) override{cout << "支付宝支付开始" << endl;bool isSecure = mode->security(uId);if (isSecure){cout << "支付宝支付成功,交易号:" << tradeId << ",金额:" << amount << endl;}else{cout << "支付宝支付失败,交易号:" << tradeId << ",金额:" << amount << endl;}}
};int main()
{PaymentMode *cypherMode = new PayByCypher();PaymentMode *faceMode = new PayByFace();Payment *wxPayment = new WxPayment(cypherMode);Payment *aliPayment = new AliPayment(faceMode);wxPayment->pay("user123", "123456", 100);aliPayment->pay("user456", "789012", 200);delete cypherMode;delete faceMode;delete wxPayment;delete aliPayment;system("pause");return 0;
}

应用场景

如果你想要拆分或重组一个具有多重功能的庞杂类 (例如能与多个数据库服务器进行交互的类), 可以使用桥接模式。

桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风险降到最低。

如果你需要在运行时切换不同实现方法, 可使用桥接模式。

当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象,只需要在抽象部分中引入实现对象,并通过接口进行交互。

顺便提一句, 最后一点是很多人混淆桥接模式和策略模式的主要原因。 记住, 设计模式并不仅是一种对类进行组织的方式, 它还能用于沟通意图和解决问题。
(在实现上有点像但是策略模式主要是针对算法,根据你的具体情况使用合适的策略算法)

与其他模式的关系

  1. 桥接、 状态模式和策略模式 (在某种程度上包括适配器) 模式的接口非常相似。 实际上, 它们都基于聚合模式——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。
  2. 你可以结合使用生成器模式和桥接模式: 主管类(定义调用构造步骤的顺序)负责抽象工作, 各种不同的生成器(会生成具体的产品)负责实现工作。
  3. 桥接模式通常会于开发前期进行设计, 使你能够将程序的各个部分独立开来以便开发。 另一方面, 适配器(为各种接口进行兼容和匹配)模式通常在已有程序中使用, 让相互不兼容的类能很好地合作。

浅薄理解,如果有错还望指正。谢谢大家。

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

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

相关文章

算法刷题Day27 | 39. 组合总和、40.组合总和II、131.分割回文串

目录 0 引言1 组合总和1.1 我的解题 2 组合总和II2.1 解题 3 分割回文串3.1 切割3.2 总结&#xff1a;分割和组合的区别 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;算法刷题Day27 | 39. 组合总和、40.…

Springboot相关知识-图片描述(学习笔记)

学习java过程中的一些笔记&#xff0c;觉得比较重要就顺手记录下来了~ 目录 一、前后端请求1.前后端交互2.简单传参3.数组集合传参4.日期参数5.Json参数6.路径参数7.响应数据8.解析xml文件9.统一返回类10.三层架构11.分层解耦12.Bean的声明13.组件扫描14.自动注入 一、前后端请…

JVM—类加载子系统

JVM—类加载子系统 JVM的类加载是通过ClassLoader及其子类来完成的。 有哪些类加载器 类加载器如下&#xff1a; 启动类加载器&#xff08;BootStrap ClassLoader&#xff09;&#xff1a;负责加载JAVA_HOME\lib目录或通过-Xbootclasspath参数指定路径中的且被虚拟机认可&am…

YB4554是一款高性价比、完全集成的高输入电压单节锂离子电池充电器

概述&#xff1a; YB4554是一款高性价比、完全集成的高输 入电压单节锂离子电池充电器。充电器使用 锂离子电池所需的CC/CV充电配置文件。该 充电器接受高达24V的输入电压&#xff0c;但当输入 电压超过OVP阈值(通常为6.8V)时禁用&#xff0c; 以防止过度功耗。24V额定值消除了…

解锁金融数据中心场景,实现国产化AD替代,宁盾身份域管为信创电脑、应用提供统一管理

随着信创国产化改造持续推进&#xff0c;越来越多的金融机构不断采购信创服务器、PC、办公软件等&#xff0c;其 IT 基础设施逐渐迁移至国产化 IT 架构下。为支撑国产化 IT 基础设施的正常使用和集中管理运维&#xff0c;某金融机构数据中心的微软Active Directory&#xff08;…

DFS-0与异或问题,有奖问答,飞机降落

代码和解析 #include<bits/stdc.h> using namespace std; int a[5][5]{{1,0,1,0,1}}; //记录图中圆圈内的值&#xff0c;并初始化第1行 int gate[11]; //记录10个逻辑门的一种排列 int ans; //答案 int logic(int x, int y, int op){…

辽宁梵宁教育课程精选:打造设计技能,提升职场竞争力

在当今快速发展的社会中&#xff0c;职场竞争日益激烈&#xff0c;拥有一门出色的技能成为了提升自身竞争力的关键。辽宁梵宁教育课程精选致力于为广大学习者提供高品质的教育资源&#xff0c;帮助学员打造设计技能&#xff0c;从而在激烈的职场竞争中脱颖而出。 设计技能在职…

如何使用PL/SQL Developer工具导出clob字段的表?

1 准备测试数据 导出测试对象&#xff1a;表test_0102&#xff0c;others字段为clob类型 --创建中间表test_0101 create table test_0101( id number, name varchar2(20), others clob);--插入100条测试数据 beginfor i in 1..100 loopinsert into test_0101 values(i,i||_a,l…

Windows11安装MySql-8.0.36安装详细教程(保姆级教程)

之前一直用的mysql5.7&#xff0c;最近导入一个项目一直报错&#xff0c;经查阅发现数据库mysql版本太老&#xff0c;今天特地重头下载安装配置一下&#xff0c;做个记录供大家参考。 下载安装包&#xff1a; 下载地址&#xff1a;https://dev.mysql.com/downloads/ 进入后选…

蓝桥杯练习笔记(十七)

蓝桥杯练习笔记&#xff08;十七&#xff09; 一、 输入样例 7 7 1000001 0100010 0010100 0001AAA 00010A0 00010A0 00010A0蓝桥官网题解&#xff1a; 该题解是用了三个循环分别对三个方向的相同字符的长度进行统计&#xff0c;找出最大长度&#xff0c;最后对找出的最长Y进…

【第十一届大唐杯全国大学生新一代信息通信技术大赛】赛题分析

赛道一 一等奖 7% 二等奖 15% 三等奖 25% 赛道二 参考文档&#xff1a; 《第十一届大唐杯全国大学生新一代信息通信技术大赛&#xff08;产教融合5G创新应用设计&#xff09;专项赛说明.pdf》 一等奖&#xff1a;7% 二等奖&#xff1a;10% 三等奖&#xff1a;20% 赛项一&am…

调用飞书获取用户Id接口成功,但是没有返回相应数据

原因&#xff1a; 该自建应用没有开放相应的数据权限。 解决办法&#xff1a; 在此处配置即可。

java实现运行脚本文件

在最近的项目中&#xff0c;有一个需求是前端传给我一个脚本文件&#xff0c;然后我需要运行脚本文件后将结果进行返回&#xff0c;那接下来就让我们看看是怎么做的吧&#xff01; public R runScripts(Integer id) {ScriptsInfo scriptsInfo this.baseMapper.selectById(id);…

QA测试开发工程师面试题满分问答5: 内存溢出和内存泄漏问题

概念阐述 内存溢出&#xff08;Memory Overflow&#xff09;和内存泄漏&#xff08;Memory Leak&#xff09;是与计算机程序中的内存管理相关的问题&#xff0c;它们描述了不同的情况。 内存溢出是指程序在申请内存时&#xff0c;要求的内存超出了系统所能提供的可用内存资源…

使用Flutter创建带有图标提示的TextField

在移动应用开发中&#xff0c;TextField是一种常用的用户输入小部件。然而&#xff0c;有时向用户提供有关他们应该输入什么的提示或说明是很有帮助的。在本教程中&#xff0c;我们将创建一个Flutter应用程序&#xff0c;演示如何在TextField旁边包含一个图标提示。 编写代码 …

1、认识MySQL存储引擎吗?

目录 1、MySQL存储引擎有哪些&#xff1f; 2、默认的存储引擎是哪个&#xff1f; 3、InnoDB和MyISAM有什么区别吗&#xff1f; 3.1、关于事务 3.2、关于行级锁 3.3、关于外键支持 3.4、关于是否支持MVCC 3.5、关于数据安全恢复 3.6、关于索引 3.7、关于性能 4、如何…

Docker容器与虚拟化技术:OpenEuler 部署 ES 与 Kibana

目录 一、实验 1.环境 2.OpenEuler 部署 ES (EalasticSearch) 3.OpenEuler 部署 Kibana 4.部署 Elasticvue插件 5.使用cpolar内网穿透 6.使用Elasticvue 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 1…

Linux 著名的sudo、su是什么?怎么用?

一、su 什么是su&#xff1f; su命令&#xff08;简称是&#xff1a;substitute 或者 switch user &#xff09;用于切换到另一个用户&#xff0c;没有指定用户名&#xff0c;则默认情况下将以root用户登录。 为了向后兼容&#xff0c;su默认不改变当前目录&#xff0c;只设…

4.6(信息差)

&#x1f30d; 山西500千伏及以上输电线路工程首次采用无人机AI自主验收 &#x1f30b; 中国与泰国将开展国际月球科研站等航天合作 ✨ 网页版微软 PowerPoint 新特性&#xff1a;可直接修剪视频 &#x1f34e; 特斯拉开始在德国超级工厂生产出口到印度的右舵车 1.马斯克&…

计数排序解读

当我们提及排序算法时&#xff0c;通常会想到冒泡排序、选择排序、插入排序、归并排序和快速排序等经典算法。然而&#xff0c;今天我们要探讨的是一种非比较型整数排序算法——计数排序。计数排序在某些特定场景下表现出色&#xff0c;具有线性的时间复杂度。下面我们将深度剖…