当前位置: 首页 > news >正文

设计模式:适配器模式(c++实现案例)

适配器模式

适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。好比日本现在就只提供110V的电压,而我的电脑就需要220V的电压,那怎么办啦?适配器就是干这活的,在不兼容的东西之间搭建一座桥梁,让二者能很好的兼容在一起工作。

在软件开发中,有的时候系统的数据和行为都正确,但接口不符合,我们应该考虑使用适配器模式,目的是使控制范围之外的一个原有对象与某个接口匹配。举个例子:在开发一个模块的时候,有一个功能点实现起来比较费劲,但是,之前有一个项目的模块实现了一样的功能点;但是现在这个模块的接口和之前的那个模块的接口是不一致的。此时,作为项目经理的你,该怎么办啦?使用适配器模式,将之前实现的功能点适配进新的项目了。

适配器模式实现步骤

  1. 适配器实现与其中一个现有对象兼容的接口
  2. 现有对象可以使用该接口安全地调用适配器方法
  3. 适配器方法被调用后将以另一个对象兼容的格式和顺序将请求传递给该对象

参考:适配器模式 --菜鸟教程

我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。

我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。

我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。

AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。

使用C++实现:

//音乐播放器
class MediaPlayer
{
public:virtual void play(string type,string name) = 0;virtual ~MediaPlayer() {};
};
//高级音乐播放类
class AdvancedMediaPlayer
{
public:virtual ~AdvancedMediaPlayer() {}virtual void playVlc(string name) = 0;virtual void playMp4(string name) = 0;
};
//支持Vlc的音乐播放器
class VlcPlayer :public AdvancedMediaPlayer
{
public:~VlcPlayer() {}void playVlc(string name)override{cout << "播放vlc类型音乐: " << name << endl;}void playMp4(string name)override {}//无需实现
};
//支持Mp4的音乐播放器
class Mp4Player :public AdvancedMediaPlayer
{
public:~Mp4Player() {}void playVlc(string name)override {}void playMp4(string name)override{cout << "播放Mp4类型音乐: " << name << endl;}
};
//接口适配器类
class MediaPlayerAdapter:public MediaPlayer
{
public:MediaPlayerAdapter(string type){if (type == "vlc"){if (pAdvance){delete pAdvance;}pAdvance = new VlcPlayer;}else if (type == "mp4"){if (pAdvance){delete pAdvance;}pAdvance = new Mp4Player;}}~MediaPlayerAdapter() { if (pAdvance!=nullptr) delete pAdvance; }void play(string type, string name)override{if (type == "vlc") pAdvance->playVlc(name);else if (type == "mp4") pAdvance->playMp4(name);}
private:AdvancedMediaPlayer* pAdvance = nullptr;
};
//整合音乐播放器
class AutioPlayer :public MediaPlayer
{
public:~AutioPlayer() { if (Mediaplayer != nullptr) delete Mediaplayer; }void play(string type, string name)override{if (type == "mp3"){cout << "播放Mp3类型音乐: " << name << endl;	//内置支持mp3类型音乐}else if(type == "vlc" || type == "mp4"){if (Mediaplayer){delete Mediaplayer;}Mediaplayer = new MediaPlayerAdapter{ type };//转换适配音乐类型Mediaplayer->play(type,name);	//播放音乐}else{cout << "不支持的音乐类型: " << type << endl;}}
private:MediaPlayerAdapter* Mediaplayer;
};int main()
{AutioPlayer* music = new AutioPlayer;music->play("mp3", "青花瓷 -周杰伦");music->play("mp4", "逆战 -张杰");music->play("vlc", "一人我饮酒醉");music->play("avi", "yellow");delete music;return 0;
}

优点

  • 降低了去实现一个功能点的难度,可以对现有的类进行包装,就可以进行使用了
  • 提高了项目质量,现有的类一般都是经过测试的,使用了适配器模式之后,不需要对旧的类进行全面的覆盖测试;
  • 总的来说,提高了效率,降低了成本。

缺点

  • 类适配器模式,由于多继承,可能会出现二义性
  • 对象适配器模式,如果过多使用适配器模式,会导致代码阅读难度增大

相关文章:

设计模式:适配器模式(c++实现案例)

适配器模式 适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。好比日本现在就只提供110V的电压&#xff0c;而我的电脑就需要220V的电压&#xff0c;那怎么办啦?适配器就是干这活的&#xff0…...

Python|每日一练|数组|回溯|哈希表|全排列|单选记录:全排列 II|插入区间|存在重复元素

1、全排列 II&#xff08;数组&#xff0c;回溯&#xff09; 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2]输出&#xff1a;[[1,1,2], [1,2,1], [2,1,1]] 示例 2&#xff1a; 输…...

Linux进程状态

Linux进程状态前言阻塞挂起Linux进程状态R运行状态S睡眠状态D磁盘休眠状态T停止状态X死亡状态Z僵尸状态僵尸进程的总结前言 在介绍Linux的进程状态之前&#xff0c;我们先做一个小调查&#xff1a; 正在运行的程序是一直在运行吗&#xff1f;或者说正在运行的程序一直在被cpu处…...

大数据第一轮复习笔记

linux: 添加用户 useradd 删除用户 userdel useradd -d指定组 添加组 groupadd 删除组 groupdel 创建目录 mkdir -p 删除目录 rm -rf 创建目录 touch cat -n 查看文件(显示行号)...

HTML面试题

HTML面试题部分知识点梳理 1.如何理解HTML语义化 让页面的内容结构化&#xff0c;便于对浏览器、引擎解析&#xff0c;易于阅读&#xff0c;便于维护理解&#xff0c;利于SEO。 2.H5的新特性 video/audio视频/音频canvas 绘画geolocation 定位 用于定位用户的位置WebSocket…...

CUDA内存管理一文理清|参加CUDA线上训练营

CUDA 内存概述 GPU的内存包括&#xff1a; 全局内存&#xff08;global memory&#xff09;常量内存&#xff08;constant memory&#xff09;纹理内存核表面内存&#xff08;texture memory&#xff09;寄存器&#xff08;register&#xff09;局部内存&#xff08;local me…...

Transformation(转换算子)

分布式代码的分析 启动spark程序的代码 在yarn中启动(没有配置环境变量) /export/server/spark/bin/spark-submit --master yarn --num-executors 6 /root/helloword.py # 配置环境变量 spark-submit --master yarn --num-executors 6 /root/helloword.py RDD的五大特征 1、…...

总结如何设计一款营销低代码可视化海报平台

背景 我所在的部门负责的是活动业务&#xff0c;每天都有很多的营销活动&#xff0c;随之而来的就是大量的H5活动页面。而这些H5活动已经沉淀出了比较固定的玩法交互&#xff0c;我们开发大多数的工作也只是在复制粘贴这种大量的重复工作。 在基于此背景下我开始了低代码平台…...

spark04-文件读取分区数据分配原理

接 https://blog.csdn.net/oracle8090/article/details/129013345?spm1001.2014.3001.5502通过上一节知道 总字节数为7 每个分区字节数为3代码val conf: SparkConf new SparkConf().setMaster("local").setAppName("wordcount")val sc: SparkContext ne…...

常见的网络安全攻击及防御技术概述

网络安全技术涉及从物理层到业务层的各个层面&#xff0c;贯穿产品设计到产品上线运营的全流程。现阶段网络攻击的方式和种类也随着互联网技术的发展而不断迭代&#xff0c;做好网络安全防护的前提是我们要对网络攻击有充分的了解。下文将抛砖引玉对常见的网络安全攻击及防御技…...

NetSuite Balancing Segment平衡段

春节假期偷了一段时间懒&#xff0c;现在开始工作了。今朝谈一个偏门题目&#xff0c;于未知领域再下一城。说这个题目偏&#xff0c;就要讲讲渊源。话说在Oracle的EBS和Fusion产品中的COA领域有个功能叫做“Balancing Segment”。 问了几位Oracle老炮&#xff0c;也说是对第二…...

Docker 中遇到的问题

1&#xff1a;docker-tomcat 篇 第一天启动主机和虚拟机都可以正常访问&#xff0c;晚上睡觉的时候就挂起关机睡觉了&#xff0c;但到了第二天主机访问不了了&#xff0c;ping 也能ping 通&#xff0c;后来停掉容器&#xff0c;重启了虚拟机就好了&#xff0c;就很离谱。 这是成…...

树莓派用默认账号和密码登录不上怎么办;修改树莓派的密码

目录 一、重置树莓派的默认账号和密码 二、修改树莓派的密码 三、超级用户和普通用户的切换 一、重置树莓派的默认账号和密码 在SD卡中根目录建立文件userconf 在userconf中输入如下内容&#xff1a; pi:$6$/4.VdYgDm7RJ0qM1$FwXCeQgDKkqrOU3RIRuDSKpauAbBvP11msq9X58c8Q…...

【LeetCode】不同的二叉搜索树 [M](卡特兰数)

96. 不同的二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&a…...

【软件相关】文献管理工具——Zotero

文章目录0 前期教程1 前言2 一些说明3 下载安装4 功能一&#xff1a;插入文献引用格式5 功能二&#xff1a;从网页下载文献pdf和题录6 功能三&#xff1a;数据多平台同步7 功能四&#xff1a;通过DOI添加条目及添加订阅8 安装xpi插件9 功能五&#xff1a;智能识别中英文文献10 …...

leetcode练习一:数组(二分查找、双指针、滑动窗口)

文章目录一、 数组理论基础二、 二分查找2.1 解题思路2.2 练习题2.2.1 二分查找(题704)2.2.2 搜索插入位置&#xff08;题35&#xff09;2.2.3 查找排序数组元素起止位置&#xff08;题34&#xff09;2.2.4 有效的完全平方数&#xff08;题367&#xff09;2.2.5 x 的平方根&…...

iPhone更新iOS 16.3出现应用卡死、闪退的问题怎么办?

在升级最新的 iOS 16.3 系统后&#xff0c;有些用户可能遇到了个别应用无法正常打开&#xff0c;卡死的异常情况。大家可以尝试通过如下方式解决问题。 1.重新启动应用&#xff1a; 如果应用出现卡死或闪退&#xff0c;可从 iPhone 屏幕由底往上滑&#xff08;或连续按两次 H…...

TCP协议原理一

文章目录一、TCP协议二、TCP工作机制1.确认应答2.超时重传3.连接管理三次握手四次挥手一、TCP协议 我们的TCP协议相比于UDP协议复杂不少&#xff0c;今天我们就来一起学习一下TCP协议报文和原理 首先我们报头第一行里的端口号和UDP的端口号是一致的&#xff0c;都是用两个字节…...

【黑马SpringCloud(6)】Sentinel解决雪崩问题

微服务保护雪崩问题服务保护技术Sentinel微服务整合Sentinel流量控制簇点链路入门练习流控模式关联链路流控效果Warm Up排队等待热点参数限流隔离和降级FeignClient整合Sentinel线程隔离(舱壁模式)实现线程隔离熔断降级慢调用异常比例/异常数授权规则获取origin给网关添加请求头…...

微信小程序 java springboot招聘求职应聘简历系统

应聘系统是基于微信小程序&#xff0c;java编程语言&#xff0c;mysql数据库&#xff0c;springboot框架&#xff0c;idea工具开发&#xff0c;本系统主要分为用户&#xff0c;企业&#xff0c;管理员三个角色&#xff0c;用户注册登陆小程序&#xff0c;查看应聘分类&#xff…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...