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.hqwc.cn/news/409572.html

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

相关文章

verilog编程题

verilog编程题 文章目录 verilog编程题序列检测电路&#xff08;状态机实现&#xff09;分频电路计数器译码器选择器加减器触发器寄存器 序列检测电路&#xff08;状态机实现&#xff09; module Detect_101(input clk,input rst_n,input data,o…

基于变换域的模版匹配

模板匹配原理 图像的空间域与其他域之间的变换&#xff0c;如傅里叶变换&#xff0c;小波变换&#xff0c;轮廓波变换&#xff0c;剪切波变换等&#xff0c;实际上是图像在其他坐标领域中的表现。在空间域中&#xff0c;图像的信息是像素值和坐标位置&#xff1b;在其他域中&a…

Spring之AOP源码(二)

书接上文 文章目录 一、简介1. 前文回顾2. 知识点补充 二、ProxyFactory源码分析1. ProxyFactory2. JdkDynamicAopProxy3. ObjenesisCglibAopProxy 三、 Spring AOP源码分析 一、简介 1. 前文回顾 前面我们已经介绍了AOP的基本使用方法以及基本原理&#xff0c;但是还没有涉…

【已解决】c语言const/指针学习笔记

本博文源于笔者正在复习const在左与在右&#xff0c;指针优先级、a,&a,*a的区别。 1、const在左与在右 int const *p const int *p int * const p int const * const p const int * const p* 在const右边&#xff0c;指向的数据不可以改变&#xff0c;可以改变地址 * 在c…

vue2使用 element表格展开功能渲染子表格

默认样式 修改后 样式2 <el-table :data"needDataFollow" border style"width: 100%"><el-table-column align"center" label"序号" type"index" width"80" /><el-table-column align"cent…

中仕公考:2024年度国考笔试分数公布,进面名单已出

2024年度考试录用公务员笔试成绩和合格分数线已经公布&#xff0c;考生们可以自行登录公务员专题网站查询成绩。 进面人员名单根据规定的面试比例&#xff0c;按照笔试成绩从高至低的顺序&#xff0c;1月14日已经公布进面名单。 没有进入面试人员名单的考生可以关注调剂&…

线性调频信号的解线调(dechirp,去斜)处理matlab仿真

线性调频信号的解线调 线性调频信号的回波模型参考信号去斜处理去斜处理傅里叶变换得到脉压结果解线调仿真总结 线性调频信号的回波模型 对于线性调频脉冲压缩雷达&#xff0c;其发射信号为&#xff1a; s ( t ) r e c t ( t T ) e x p ( j π μ t 2 ) \begin{equation} s(…

STM32——ADC知识总结及多通道采样实验

1.ADC概念 ADC&#xff0c;全称&#xff1a;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 2 STM32各系列ADC的主要特性 3.F4框图 4.转换序列与转换时间 A/D转换被组织为两组&#xff1a;规则组&#xff08;常规转换组&#xff09;和注入组&#xff08;注入…

PCL ISS关键点提取(C++详细过程版)

边界提取 一、概述二、代码实现三、结果展示PCL ISS关键点提取(C++详细过程版)由CSDN点云侠原创,爬虫自重。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 ISS关键点提取在PCL里有现成的调用函数,具体算法原理和实现代码见:PCL ISS关键点提…

【Spring 篇】深入探索:Spring集成Web环境的奇妙世界

嗨&#xff0c;亲爱的小白们&#xff01;欢迎来到这篇有关Spring集成Web环境的博客。如果你曾对如何在Spring中构建强大的Web应用程序感到好奇&#xff0c;那么这里将为你揭示Web开发的神秘面纱。我们将用情感丰富、语句通顺的文字&#xff0c;以小白友好的方式&#xff0c;一探…

机器视觉系统选型-参数—景深

镜头在垂直方向上&#xff0c;能清晰成像的空间距离(清晰成像范围)&#xff0c;称为景深