C++ 设计模式之桥接模式

【声明】本题目来源于卡码网(题目页面 (kamacoder.com))

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】


【简介】什么是桥接模式

        桥接模式(Bridge Pattern)是⼀种结构型设计模式,它的UML图很像⼀座桥,它通过将【抽象部分】与【实现部分】分离,使它们可以独⽴变化,从⽽达到降低系统耦合度的⽬的。桥接模式的主要⽬的是通过组合建⽴两个类之间的联系,⽽不是继承的⽅式。
        举个简单的例⼦,图形编辑器中,每⼀种图形都需要蓝⾊、红⾊、⻩⾊不同的颜⾊,如果不使⽤桥接模式,可能需要为每⼀种图形类型和每⼀种颜⾊都创建⼀个具体的⼦类,⽽使⽤桥接模式可以将图形和颜⾊两个维度分离,两个维度都可以独⽴进⾏变化和扩展,如果要新增其他颜⾊,只需添加新的 Color ⼦类,不影响图形类;反之亦然。


【基本结构】

桥接模式的基本结构分为以下⼏个⻆⾊:

  • 抽象Abstraction :⼀般是抽象类,定义抽象部分的接⼝,维护⼀个对【实现】的引⽤。
  • 修正抽象RefinedAbstaction :对抽象接⼝进⾏扩展,通常对抽象化的不同维度进⾏变化或定制。
  • 实现Implementor : 定义实现部分的接⼝,提供具体的实现。这个接⼝通常是抽象化接⼝的实现。
  • 具体实现ConcreteImplementor :实现实现化接⼝的具体类。这些类负责实现实现化接⼝定义的具体操作。

 

         再举个例⼦,遥控器就是抽象接⼝,它具有开关电视的功能,修正抽象就是遥控器的实例,对遥控器的功能进⾏实现和扩展,⽽电视就是实现接⼝,具体品牌的电视机是具体实现,遥控器中包含⼀个对电视接⼝的引⽤,通过这种⽅式,遥控器和电视的实现被分离,我们可以创建多个遥控器,每个遥控器控制⼀个品牌的电视机,它们之间独⽴操作,不受电视品牌的影响,可以独⽴变化。


【简易实现】

        下⾯是实现桥接模式的基本步骤:(以Java代码作以说明)

1. 创建实现接口

interface Implementation {void operationImpl();
}

2. 创建具体实现类:实际提供服务的对象

class ConcreteImplementationA implements Implementation {@Overridepublic void operationImpl() {// 具体实现A}
}
class ConcreteImplementationB implements Implementation {@Overridepublic void operationImpl() {// 具体实现B}
}

3. 创建抽象接⼝:包含⼀个对实现化接⼝的引⽤。

public abstract class Abstraction {protected IImplementor mImplementor;public Abstraction(IImplementor implementor) {this.mImplementor = implementor;} public void operation() {this.mImplementor.operationImpl();}
}

4. 实现抽象接⼝,创建RefinedAbstaction 类

class RefinedAbstraction implements Abstraction {private Implementation implementation;public RefinedAbstraction(Implementation implementation) {this.implementation = implementation;}@Overridepublic void operation() {// 委托给实现部分的具体类implementation.operationImpl();}
}

5. 客户端使⽤

// 客户端代码
public class Main {public static void main(String[] args) {// 创建具体实现化对象Implementation implementationA = new ConcreteImplementationA();Implementation implementationB = new ConcreteImplementationB();// 使⽤扩充抽象化对象,将实现化对象传递进去Abstraction abstractionA = new RefinedAbstraction(implementationA);Abstraction abstractionB = new RefinedAbstraction(implementationB);// 调⽤抽象化的操作abstractionA.operation();abstractionB.operation();}
}

【使用场景】

         桥接模式在⽇常开发中使⽤的并不是特别多,通常在以下情况下使⽤:

  • 当⼀个类存在两个独⽴变化的维度,⽽且这两个维度都需要进⾏扩展时,使⽤桥接模式可以使它们独⽴变化,减少耦合。
  • 不希望使⽤继承,或继承导致类爆炸性增⻓

        总体⽽⾔,桥接模式适⽤于那些有多个独⽴变化维度、需要灵活扩展的系统


【编码部分】

1. 题目描述

        小明家有一个万能遥控器,能够支持多个品牌的电视。每个电视可以执行开机、关机和切换频道的操作,请你使用桥接模式模拟这个操作。

2. 输入描述

        第一行是一个整数 N(1 <= N <= 100),表示后面有 N 行输入。接下来的 N 行,每行包含两个数字。第一个数字表示创建某个品牌的遥控和电视,第二个数字表示执行的操作。其中,0 表示创建 Sony 品牌的电视,1 表示创建 TCL 品牌的遥控和电视;2 表示开启电视、3表示关闭电视,4表示切换频道。        

3. 输出描述

        对于每个操作,输出相应的执行结果。

4. C++编码实例

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file BridgeMode.hpp
* @brief 桥接模式
* @autor 写代码的小恐龙er
* @date 2024/01/11
*/#include <iostream>
#include <string>using namespace std;// 前置声明
// 实现化接口
class TV;
// ======== 第一个维度的扩充 ========// 具体实现类1 -- Sony Tv
class SonyTv;
// 具体实现类2 -- TCL Tv
class TclTv;// ----------------------------------// 抽象化接口
class RemoteControl;
// ======== 第二个维度的扩充 ========// 实现抽象化接口 -- 开机
class TurnOn;
// 实现抽象化接口 -- 关机
class TurnOff;
// 实现抽象化接口 -- 切换频道
class SwitchChannel;// 实现化接口
class TV
{// 接口函数
public:virtual void TurnOnTV() = 0;virtual void TurnOffTV() = 0;virtual void SwitchTVChannel() = 0;
};// 具体实现类1 -- Sony Tv
class SonyTv : public TV
{public:// 重载接口函数void TurnOnTV(){std::cout << "Sony TV is ON" << endl;}void TurnOffTV(){std::cout << "Sony TV is OFF" << endl;}void SwitchTVChannel(){std::cout << "Switching Sony TV channel" << endl;}
};// 具体实现类2 -- TCL Tv
class TclTv : public TV
{
public:// 重载接口函数void TurnOnTV(){std::cout << "TCL TV is ON" << endl;}void TurnOffTV(){std::cout << "TCL TV is OFF" << endl;}void SwitchTVChannel(){std::cout << "Switching TCL TV channel" << endl;}
};// 抽象化接口
class RemoteControl
{
// 抽象化接口类持有实现化接口类的实例
protected:TV *_tv;public:// 重载构造函数RemoteControl(){}RemoteControl(TV *tv){this->_tv = tv;}// 提供抽象类接口函数virtual void OperationMode() = 0;
};// 实现抽象化接口 -- 开机
class TurnOn : public RemoteControl
{
private:// 实现抽象接口类持有实现化接口类的实例TV *_tv;public:// 重载构造函数 以便后续调用能传入抽象类TurnOn(TV *tv){this->_tv = tv;}// 重载抽象类接口函数void OperationMode() override {this->_tv->TurnOnTV();}};
// 实现抽象化接口 -- 关机
class TurnOff : public RemoteControl
{
private:// 实现抽象接口类持有实现化接口类的实例TV *_tv;public:// 重载构造函数 以便后续调用能传入抽象类TurnOff(TV *tv){this->_tv = tv;}// 重载抽象类接口函数void OperationMode() override {this->_tv->TurnOffTV();}
};// 实现抽象化接口 -- 切换频道
class SwitchChannel : public RemoteControl
{
private:// 实现抽象接口类持有实现化接口类的实例TV *_tv;public:// 重载构造函数 以便后续调用能传入抽象类SwitchChannel(TV *tv){this->_tv = tv;}// 重载抽象类接口函数void OperationMode() override {this->_tv->SwitchTVChannel();}    };int main()
{// 执行操作的数量int operationNum = 0;// 输入std::cin >> operationNum;// 创建实现化接口TV *tv = nullptr;RemoteControl *control = nullptr;// 遍历输入for(int i = 0; i < operationNum; i++){// 电视机类型int tvType = -1;// 遥控器操作类型int controlType = -1;// 输入std:: cin >> tvType >> controlType;// 电视机类型if(!tvType){tv = new SonyTv();}else if(tvType == 1){tv = new TclTv();}else tv = nullptr;// 若输入指令错误则直接返回if(tv == nullptr) return 0;// 遥控器操作类型if(controlType == 2){control = new TurnOn(tv);}else if(controlType == 3){control = new TurnOff(tv);}else if(controlType == 4){control = new SwitchChannel(tv);}else control = nullptr;// 若输入指令错误则直接返回if(control == nullptr) return 0;// 执行操作control->OperationMode();}delete tv;tv = nullptr;delete control;control = nullptr;return 0;
}

......

To be continued.

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

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

相关文章

倍福嵌入式PLC开发团队建设

倍福嵌入式PLC开发工程师确实比较难找&#xff0c;这是因为这个领域需要具备丰富的专业知识和技能&#xff0c;而且经验越丰富的工程师越难找到。以下是一些可能导致倍福嵌入式PLC开发工程师难找的原因&#xff1a; 具备相关技能的工程师数量相对较少&#xff1a;嵌入式PLC开发…

XUbuntu22.04之免费思维导图工具(二百零六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Kafka集群的安装与配置

一、安装JDK 1、在usr目录下新建Java目录&#xff0c;然后将下载的JDK拷贝到这个新建的Java目录中1 创建目录命令&#xff1a;mkdir /usr/java 2、进入到Java目录中解压下载的JDK 解压命令&#xff1a;tar -zxvf jdk-18_linux-x64_bin.tar.gz 在1主机上&#xff0c;将安装包…

SQL-用户管理与用户权限

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

FPGA之LUT

由于FPGA需要被反复烧写,它实现组合逻辑的基本结构不可能像ASIC那样通过固定的与非门来完成,而只能采用一种易于反复配置的结构。查找表可以很好地满足这一要求,目前主流FPGA都采用了基于SRAM工艺的查找表结构。LUT本质上就是一个RAM.它把数据事先写入RAM后,每当输入一个信号就…

【Python】tensor格式数据转为图像,并保存图像详解和示例

在项目中遇到一个tensor格式的数据&#xff0c;要保存为图像&#xff0c;此文对转换过程通过示例分享&#xff0c;以记录学习过程和帮助大家遇到同类问题时使用。 import torch import cv2 import numpy as np# 创建一个示例张量&#xff08;tensor&#xff09; input_tensor …

纯c实现顺序表 数据结构大全

我们已经知道数组是连续的内存地址&#xff0c;顺序表是由数组为基础的一种数据结构&#xff0c;拥有比数组更多的功能&#xff0c;在概念上属于线性结构&#xff0c;跟链表不同的是&#xff0c;顺序表在物理结构上也是线性的 什么是数据结构&#xff1f; 当我们想要使⽤⼤量使…

云计算平台建设总体技术方案详细参考

第1章. 基本情况 1.1. 项目名称 XX 公司 XX 云计算平台工程。 1.2. 业主公司 XX 公司。 1.3. 项目背景 1.3.1. XX 技术发展方向 XX&#xff0c;即运用计算机、网络和通信等现代信息技术手段&#xff0c;实现政府组织结构和工作流程的优化重组&#xff0c;超越时间、空间…

开源28181协议视频平台搭建流程

最近项目中用到流媒体平台&#xff0c;java平台负责信令部分&#xff0c;c平台负责流媒体处理&#xff0c;找了评分比较好的开源项目 https://gitee.com/pan648540858/wvp-GB28181-pro 流媒体服务基于 c写的 https://github.com/ZLMediaKit/ZLMediaKit 说明文档&#xff1a;h…

Visual Studio Code常用设置

此处用于记录下本人所使用 VScode 的使用习惯。其中主要包括&#xff1a;界面&#xff0c;主题&#xff0c;光标&#xff0c;文件保存等选项。 VSCode 用户区设置 相关介绍命令行方式进行配置可视化组件方式进行配置 更新 相关介绍 基本原理&#xff1a; Visual Studio Code 会…

【电子通识】各国电源插头标准和电压标准

在使用仪器时&#xff0c;通常会在使用之前去看下规格书。比如安装指南、快速使用指南等等来提取我们需要的信息。 一般大型的仪器供应商会卖往不同的国家&#xff0c;所以都会配置多种电源线。如下所示规格书中对仪器的电源线种类进行了说明。其中有中国、美国、加拿大、日本…

设计模式入门

0. 类图 1. 设计原则 1.单一职责原则&#xff1a;每个类只有一个功能 2.开放封闭原则&#xff1a;模块和函数应该对扩展开放(对提供方)&#xff0c;对修改关闭(对使用方) 3.里氏代换原则&#xff1a;子类拥有父类的所有方法和属性&#xff0c;从而可以减少创建类的工作量 4.依…

20240115在ubuntu20.04.6下给GTX1080M显卡安装驱动程序和CUDA

20240115在ubuntu20.04.6下给GTX1080M显卡安装驱动程序和CUDA 2024/1/15 18:05 百度搜索&#xff1a;ubuntu gtx1080m cuda https://blog.csdn.net/wb4916/article/details/129462103 20230311给Ubuntu18.04下的GTX1080M安装驱动 https://www.cnblogs.com/djiankuo/p/5886605.h…

每日一练:LeeCode-144、145、94.二叉树的前中后序遍历【二叉树】

本文是力扣LeeCode-144、145、94.二叉树的前中后序遍历 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode前序遍历、中序遍历、后序遍历。 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序遍历。 给定一个二叉树的根…

概率论与数理统计————3.随机变量及其分布

一、随机变量 设E是一个随机试验&#xff0c;S为样本空间&#xff0c;样本空间的任意样本点e可以通过特定的对应法则X&#xff0c;使得每个样本点都有与之对应的数对应&#xff0c;则称XX&#xff08;e&#xff09;为随机变量 二、分布函数 分布函数&#xff1a;设X为随机变量…

C# wpf 实现任意控件(包括窗口)更多调整大小功能

WPF拖动改变大小系列 第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能&#xff08;本章&#xff09; 文章目录 WPF拖动改变大小系列前言一、添加的功能1、任意控件Drag…

Flink 处理函数(1)—— 基本处理函数

在 Flink 的多层 API中&#xff0c;处理函数是最底层的API&#xff0c;是所有转换算子的一个概括性的表达&#xff0c;可以自定义处理逻辑 在处理函数中&#xff0c;我们直面的就是数据流中最基本的元素&#xff1a;数据事件&#xff08;event&#xff09;、状态&#xff08;st…

基于SSM的项目监管系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

xtdrone用键盘控制无人机飞行 无法起飞

运行案例 解锁无人机螺旋桨转动但无法起飞 也未报错 解决方法&#xff1a; 在QGC中修改&#xff1a;PX4飞控EKF配置 将PX4使用的EKF配置为融合GPS的水平位置与气压计高度。 如果我们想使用视觉定位&#xff0c;就需要把修改配置文件。 此修改意味着EKF融合来自mavros/vision_…

基于SSM的网上招聘系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…