【设计模式】适配器模式:让不兼容的接口和谐共处
引言
在软件开发中,我们经常会遇到这样的情况:两个已经存在的接口无法直接协同工作,但我们又希望它们能够无缝对接。这时,适配器模式就派上用场了。适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。通过这种方式,原本不兼容的接口可以一起工作。
本文将通过生动的比喻、详细的代码示例和常见应用场景,帮助你轻松掌握适配器模式的核心概念和实际应用。
1. 适配器模式的核心概念
1.1 什么是适配器模式?
适配器模式就像是现实生活中的电源适配器。假设你有一个美国的电器设备,但你在中国使用时,插头不匹配。这时,你需要一个适配器来将美国的插头转换成中国的插座。同样,在软件中,适配器模式通过一个中间层(适配器)来转换一个类的接口,使其与客户端期望的接口兼容。
1.2 适配器模式的结构
适配器模式主要由以下几个角色组成:
- 目标接口(Target):客户端所期望的接口。
- 适配者(Adaptee):需要被适配的类或接口。
- 适配器(Adapter):将适配者的接口转换成目标接口的类。
适配器模式有两种实现方式:类适配器和对象适配器。
- 类适配器:通过多重继承来实现适配。
- 对象适配器:通过组合来实现适配。
在C++中,由于多重继承的复杂性,我们通常更倾向于使用对象适配器。
2. 适配器模式的代码示例
为了更好地理解适配器模式,我们来看一个具体的例子。假设我们有一个旧的日志系统(Adaptee
),它提供了一个LogToFile
方法,用于将日志记录到文件中。但现在,客户端期望使用一个新的日志接口(Target
),该接口提供了一个Log
方法。我们需要一个适配器来使旧的日志系统能够与新的接口兼容。
2.1 定义目标接口
首先,我们定义客户端所期望的目标接口:
#include <string>class Logger {
public:virtual void Log(const std::string& message) = 0;virtual ~Logger() {}
};
2.2 定义适配者
接下来,定义需要被适配的旧日志系统:
class OldLogger {
public:void LogToFile(const std::string& message) {// 模拟将日志记录到文件std::cout << "Logging to file: " << message << std::endl;}
};
2.3 实现适配器
现在,我们实现适配器类,它继承自目标接口Logger
,并持有一个OldLogger
的实例:
class LoggerAdapter : public Logger {
private:OldLogger* oldLogger;
public:LoggerAdapter(OldLogger* logger) : oldLogger(logger) {}void Log(const std::string& message) override {oldLogger->LogToFile(message);}
};
2.4 客户端使用
客户端代码可以这样使用适配器:
#include <iostream>int main() {OldLogger oldLogger;LoggerAdapter adapter(&oldLogger);adapter.Log("This is a test message.");return 0;
}
在上面的例子中,LoggerAdapter
类充当了适配器的角色,它将OldLogger
的LogToFile
方法适配成了Logger
接口的Log
方法。这样,客户端就可以通过Logger
接口来使用旧的日志系统,而无需修改旧的代码。
3. 适配器模式的应用场景
适配器模式在实际开发中有很多应用场景,以下是几个常见的例子:
3.1 遗留系统的集成
当我们需要将一个遗留系统集成到新的系统中时,遗留系统的接口可能与新系统不兼容。这时,可以使用适配器模式来使遗留系统与新系统协同工作,而无需修改遗留系统的代码。
3.2 第三方库的适配
在使用第三方库时,如果库的接口与我们的系统不匹配,我们可以使用适配器模式来封装第三方库的接口,使其符合我们的系统要求。
3.3 接口的统一
在某些情况下,我们可能有多个类似的类,但它们的接口不一致。使用适配器模式,我们可以为这些类创建统一的接口,从而简化客户端代码。
4. 适配器模式的优缺点
4.1 优点
- 提高代码的复用性:通过适配器,我们可以重用现有的类,而无需修改其代码。
- 增强系统的灵活性:适配器模式允许我们在不改变现有代码的情况下,添加新的功能或集成新的系统。
- 解耦客户端和适配者:客户端只需要与目标接口交互,而不需要了解适配者的具体实现。
4.2 缺点
- 增加系统的复杂性:引入适配器类会增加系统的类数量,从而可能增加系统的复杂性。
- 性能开销:在某些情况下,适配器可能会引入额外的性能开销,尤其是在频繁调用的场景中。
5. 总结
适配器模式是一种非常实用的设计模式,它通过一个中间层来转换接口,使不兼容的类能够协同工作。在C++中,我们通常使用对象适配器来实现这一模式。通过本文的讲解和代码示例,相信你已经对适配器模式有了深入的理解。在实际开发中,合理地应用适配器模式可以提高代码的复用性和系统的灵活性,帮助我们更好地应对变化的需求。
相关文章:
【设计模式】适配器模式:让不兼容的接口和谐共处
引言 在软件开发中,我们经常会遇到这样的情况:两个已经存在的接口无法直接协同工作,但我们又希望它们能够无缝对接。这时,适配器模式就派上用场了。适配器模式(Adapter Pattern)是一种结构型设计模式&…...
QuickAPI 核心能力解析:构建数据服务化的三位一体生态
在企业数据资产化运营的进程中,如何打破数据开发与共享的效率瓶颈,实现从 “数据可用” 到 “数据好用” 的跨越?麦聪软件的 QuickAPI 给出了系统性答案。作为 SQL2API 理念的标杆产品,QuickAPI 通过SQL 编辑器、数据 API、数据市…...
vue3 elementPlus中el-tree-select封装和自定义模糊搜索
:filter-node-method"filterNodeMethod"此方法对应的是模糊搜索,// 获取树形数据 const loadTreeData async () > {try {const res await deviceTree()if (res.data) {treeData.value res.data// 构建 ID 到标签的映射idMap.value new Map()const …...
【哈夫曼树和哈夫曼编码是什么?】
哈夫曼树和哈夫曼编码是数据压缩领域中的核心概念,它们基于字符出现的频率来实现高效编码。下面是详细介绍,通俗易懂。 一、什么是哈夫曼树(Huffman Tree)? 哈夫曼树是一种最优二叉树,用于构造最短的前缀编…...
量子纠缠物理本质、技术实现、应用场景及前沿研究
以下是关于 量子纠缠(Quantum Entanglement) 的深度解析,涵盖物理本质、技术实现、应用场景及前沿研究,以技术视角展开: 一、量子纠缠的物理本质 1. 核心定义 量子纠缠是多个量子系统(如粒子)间的一种关联状态,表现为: 非局域性:纠缠态粒子无论相距多远,测量其中一…...
时间的重构:科技如何重塑人类的时间感知与存在方式
时间是人类认知的基石,也是科技发展的终极命题。从石英钟到量子计时器,从日晷到区块链时间戳,技术不断重构着我们对时间的理解与利用。然而,当人工智能、量子计算和脑机接口等前沿技术开始挑战时间的线性本质时,我们不…...
现代测试自动化框架教程:Behave接口测试与Airtest移动端UI自动化
前言 我发现每天还是陆陆续续有人在看我之前写的自动化框架搭建的文档;即使很早就有新的框架,更好的选择出来了;所以特别写了这一篇目前大厂也在使用的;日活400w有实际落地的自动化测试架构方案; 随着测试技术…...
linux-设置每次ssh登录服务器的时候提醒多久需要修改密码
在 Linux 系统中,你可以通过设置 motd(Message of the Day)或 sshd 配置来在用户通过 SSH 登录时提醒他们密码即将过期。以下是具体步骤: 方法 1: 使用 motd 文件 motd 文件在用户登录时显示,你可以通过脚本动态生成内容,提醒用户密码过期时间。 编辑 /etc/motd 文件:…...
JAVA如何操作文件?(超级详细)
目录 一、认识文件和相关知识 1.认识文件 2.⽬录 3.⽂件路径(Path) 4.文本文件和二进制文件的区分 二、File类操作文件 1.构造方法 2.方法 2.1 方法表 2.2 get相关的方法和构造方法 2.2.1 “.” 和 “..” 2.3 is相关的方法 2.4 删除相关…...
Debian服务器挂载外部存储设备的完整指南
在 Debian 系统中挂载外部存储设备(如 U 盘、移动硬盘、SSD)是服务器运维和桌面使用中非常常见的操作。本文将为你详细拆解从识别设备、格式化到手动/自动挂载的全过程,适合新手到进阶用户参考。 一、准备阶段:插入存储设备并识别 1. 插入外部设备后查看…...
搭建一个网站需要选择什么配置的服务器?
一般要考虑网站规模、技术需求等因素来进行选择。 小型网站:个人博客、小型企业官网等日均量在 1000 以内的网站,一般推荐2 核 CPU、4GB 内存、50GB 硬盘,带宽 1 - 5M。如果是纯文字内容且图片较少的小型网站,初始阶段 1 核 CPU、…...
基于STM32与NB-IoT的智慧路灯远程监控系统
标题:基于STM32与NB-IoT的智慧路灯远程监控系统 内容:1.摘要 随着城市化进程的加快,路灯作为城市基础设施的重要组成部分,其管理和维护的智能化需求日益增长。本文的目的是设计并实现一种基于STM32与NB - IoT的智慧路灯远程监控系统。采用STM32微控制器…...
【高阶数据结构】第三弹---图的存储与遍历详解:邻接表构建与邻接矩阵的BFS/DFS实现
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【高阶数据结构】 目录 1、图的存储结构 1.1、邻接表 1.1.1、边的结构 1.1.2、图的基本结构 1.1.3、图的创建 1.1.4、获取顶点下…...
Tmi-clnet:从影像学、临床和放射学数据融合判断慢性肝病预后的三模态相互作用网络——医学图像论文学习,论文源码下载
论文地址:https://arxiv.org/pdf/2502.00695v1 源码地址:https://github.com/Mysterwll/liver 一、主要内容 本文提出了名为TMI-CLNet的三模态交互网络,用于慢性肝病的预后评估。具体来说,开发了一个模态内聚合模块和一个三模态…...
SpringBoot整合POI实现Excel文件的导出与导入
使用 Apache POI 操作 Excel文件,系列文章: 《SpringBoot整合POI实现Excel文件的导出与导入》 《SpringMVC实现文件的上传与下载》 《C#使用NPOI导出Excel文件》 《NPOI使用手册》 1、Apache POI 的介绍 Apache POI 是一个基于 Java 的开源库,专为读写 Microsoft Office 格…...
编程行业语言学习与竞争剖析:探寻冷门中的机遇
编程行业语言学习与竞争剖析:探寻冷门中的机遇 在编程领域不断拓展与演变的进程里,“编程行业什么开发语言竞争小易学习” 这一问题,始终萦绕在众多编程爱好者与初涉此道者的心头。今日,我(卓伊凡,优雅草的…...
数据库学习通期末复习二
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
道可云人工智能每日资讯|首届世界人工智能电影节在法国尼斯举行
道可云元宇宙每日简报(2025年4月15日)讯,今日元宇宙新鲜事有: 杭州《西湖区打造元宇宙产业高地的扶持意见》发布 杭州西湖区人民政府印发《西湖区打造元宇宙产业高地的扶持意见》。该意见已于4月4日正式施行,有效期至…...
Python 冷门魔术方法
__init_subclass__ https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__ Python 3.6 新增。 父类派生子类后会调用该方法,方法中 cls 指向派生出的子类。 若__init_subclass__被定义为普通方法,将会被隐式转换为类方法&…...
【已更新完毕】2025泰迪杯数据挖掘竞赛C题数学建模思路代码文章教学:竞赛智能客服机器人构建
基于大模型的竞赛智能客服机器人构建 摘要 随着国内学科和技能竞赛的增多,参赛者对竞赛相关信息的需求不断上升,但传统人工客服存在效率低、成本高、服务不稳定和用户体验差的问题。因此,设计一款智能客服机器人,利用人工智能技术…...
L1-028 判断素数
L1-028 判断素数 L1-028 判断素数 - 团体程序设计天梯赛-练习集 (pintia.cn) 题解 素数概念:一个数如果只能被1和这个数本身整除,那么这个数就是素数。 并且1不是素数,2是素数。 因为题目中数最长位数是9位数,所以我用了long…...
向量数据库
目录标题 阶段二:核心技术深入学习阶段三:工具与实践 1. 基础概念问题:什么是向量数据库?它与传统关系型数据库的区别是什么?问题:向量数据库的核心数据结构是什么?为什么向量适合用于高维数据&…...
《Vue3学习手记2》
今天主要学习Vue3中的数据监视: ps: 代码中的注释写的很详细,这样更有利于理解 watch 作用: 监视数据的变化(和Vue2中watch作用一致) 特点: Vue3中的watch只能监视以下四种数据: ref创建定义的数据(基本类型、对象类型)reactiv…...
zigbee和wifi都是无线通信,最大区别是低功耗,远距离!
zigbee和wifi都属于短距离无线通信技术,都使用了2.4GHz的无线频段,并采用了直接序列扩频传输技术(DSSS)。并广泛应用于人们的生产生活之中。但是,它们之间却存在很大区别。 1、传输速率不同 ①、zigbee传输速率 zigb…...
JavaWeb开发 Servlet底层 Servlet 过滤器 过滤器和拦截器 手写一个限制访问路径的拦截器
目录 万能图 过滤器自我理解 案例 实现Filter 接口 配置文件 web.xml 将过滤器映射到 servlet 用处 拦截器 手写案例 重写 preHandle() 方法 拦截处理 重写 postHandle() 方法 后处理 重写 afterHandle() 方法 完成处理 代码 如何配置拦截器 万能图 还是看一下这张…...
Zookeeper三台服务器三节点集群部署(docker-compose方式)
1. 准备工作 - 服务器:3 台服务器,IP 地址分别为 `10.10.10.11`、`10.10.10.12`、`10.10.10.13`。 - 安装 Docker:确保每台服务器已安装 Docker 和 Docker Compose。 - 网络通信:确保三台服务器之间可以通过 IP 地址互相访问,并开放以下端口: - `2181`:Zookeeper 客户…...
从北京到大同,走过600里,跨越1000年。
人们都说,在中国,地下文物看陕西,地上文物看山西,因此在一个月之前就想来山西走一走,看一看,感受一下我泱泱大国的中华千年的历史积淀。 1、出发前的小花絮 于是,就在清明车票开卖的一瞬间&…...
鸿蒙NEXT开发全局上下文管理类(ArkTs)
type CacheValue string | number | boolean | object;/*** 全局上下文管理类,用于存储和管理全局数据。* author: 鸿蒙布道师* since: 2025/04/15*/ export class GlobalContext {private static instance: GlobalContext;private _objects new Map<string, C…...
【论文阅读】Orion: Online Backdoor Sample Detection via Evolution Deviance
摘要 现有的后门输入检测策略依赖于一个假设,即正常样本和被投毒样本在模型的特征表示中是可分离的。然而,这一假设可能会被先进的特征隐藏型后门攻击打破。在本文中,我们提出了一种新颖的检测框架,称为Orion(通过进化…...
Redis之缓存雪崩
Redis之缓存雪崩 文章目录 Redis之缓存雪崩一、什么是缓存雪崩1. 定义2.核心原因① 缓存集中过期② 缓存服务故障③ 资源竞争或流量激增 3. 影响 二、缓存雪崩常见解决方案1. 分散缓存过期时间2. 多级缓存架构3. 缓存高可用设计4. 熔断与降级机制5. 缓存预热6. …...
【HarmonyOS 5】AttributeModifier和AttributeUpdater详解
【HarmonyOS 5】AttributeModifier和AttributeUpdater区别详解 一、AttributeModifier和AttributeUpdater的定义和作用 1. AttributeModifier是ArkUI组件的动态属性,提供属性设置功能。开发者可使用attributeModifier方法,通过自定义实现AttributeModi…...
C# + Python混合开发实战:优势互补构建高效应用
文章目录 前言🥏一、典型应用场景1. 桌面应用智能化2. 服务端性能优化3. 自动化运维工具 二、四大技术实现方案方案1:进程调用(推荐指数:★★★★☆)方案2:嵌入Python解释器(推荐指数࿱…...
鸿蒙开发中,@Extend、@Styles 和 @Builder 的区别
在鸿蒙(HarmonyOS)开发中,Extend、Styles 和 Builder 是三种常用的装饰器,用于提升代码复用性和可维护性。以下是它们的详细介绍和示例: 1. Extend:扩展组件样式 说明: 功能:用于…...
poll为什么使用poll_list链表结构而不是数组 - 深入内核源码分析
一:引言 在Linux内核中,poll机制是一个非常重要的I/O多路复用机制。它允许进程监视多个文件描述符,等待其中任何一个进入就绪状态。poll的内部实现使用了poll_list链表结构而不是数组,这个设计选择背后有其深层的技术考量。本文将从内核源码层面深入分析这个设计决…...
从健康干预到成本优化:健康管理系统如何驱动企业降本增效?
在全球经济竞争日益激烈的背景下,企业正面临劳动力成本上升、员工健康问题频发、医疗支出居高不下等多重挑战,在当今商业环境中,企业的降本增效至关重要,而员工的健康状况是影响企业成本和效率的关键因素之一。健康管理系统作为一…...
12【模块学习】DS18B20(二):高级使用
DS18B20 1、改变采样分辨率2、总线上有多个设备的使用2.1、获取总线上单个设备的ROM码2.2、通过匹配ROM指令使用总线上多个设备 3、项目:4路温度检测LCD显示 1、改变采样分辨率 需要改变采样的分辨率,则需要向暂存器的配置寄存器中写入配置参数。在向寄…...
NLP高频面试题(四十三)——什么是人类偏好对齐中的「对齐税」(Alignment Tax)?如何缓解?
一、什么是「对齐税」(Alignment Tax)? 所谓「对齐税」(Alignment Tax),指的是在使人工智能系统符合人类偏好的过程中,所不可避免付出的性能损失或代价。换句话说,当我们迫使AI遵循人类价值观和规范时,AI系统往往无法达到其最大理论性能。这种性能上的妥协和折衷,就…...
线代第二章矩阵第一课:矩阵的概念
一、矩阵的概念 矩阵 i还是表示的是行,j表示的是列;行数未必等于列数 同型矩阵: A,B行数相等,列数相等 矩阵相等: 同型矩阵,且对应元素相等 零矩阵: 所有元素均为0 二、特殊矩阵 方阵 行数…...
如何获取Google Chrome的官方最新下载链接【获取教程】
一、为什么选择官方下载链接 安装谷歌浏览器的最安全方式始终是通过其官方网站。非官方渠道可能存在版本落后、功能缺失,甚至潜藏恶意插件等风险。因此,获取Google Chrome的官方最新下载链接,是保障浏览器安全与性能的重要前提。 此外&…...
软件测试——BUG概念
一、软件测试生命周期 软件测试贯穿于软件的整个生命周期 软件测试的生命周期指测试流程,每个阶段有不同的目标和交付产物 需求分析 从用户角度考虑软件需求是否合理 从技术角度考虑技术上是否可行,是否有优化空间 从测试角度考虑是否存在业务逻辑错误…...
Docker安装 (centos)
1.安装依赖包: sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2.删除已有的 Docker 仓库文件(如果有): sudo rm -f /etc/yum.repos.d/docker-ce.repo 3.添加阿里云的 Docker 仓库: sudo yum…...
MySQL数据库 - 存储引擎
存储引擎 此笔记参考黑马教程,仅学习使用,如有侵权,联系必删 文章目录 存储引擎1. MySQL 体系结构2. 存储引擎简介2.1 语法代码演示 3. 存储引擎特点InnoDB介绍特点文件逻辑存储结构 MyISAM介绍特点文件 Memory介绍特点文件 总结 4. 存储引擎…...
【网络篇】UDP协议的封装分用全过程
大家好呀 我是浪前 今天讲解的是网络篇的第二章:UDP协议的封装分用 我们的协议最开始是OSI七层网络协议 这个OSI 七层网络协议 是计算机的大佬写的,但是这个协议一共有七层,太多了太麻烦了,于是我们就把这个七层网络协议就简化为…...
数据结构——布隆过滤器
目录 一、什么是布隆过滤器? 二、布隆过滤器的原理 三、布隆过滤器的特点 一、什么是布隆过滤器? 布隆过滤器是一种空间效率高、适合快速检索的数据结构,用于判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来…...
pytorch实现逻辑回归
pytorch实现逻辑回归 数据准备,参数初始化前向计算计算损失计算梯度更新参数 在官网上找到线性函数的公式表达式 import torch from sklearn.datasets import load_iris # from sklearn.model_selection import train_test_split #train_test_split是sklearn中的…...
03-Spring Cloud Gateway 深度解析:从核心原理到生产级网关实践
Spring Cloud Gateway 深度解析:从核心原理到生产级网关实践 一、网关技术演进与 Spring Cloud Gateway 定位 1. 微服务网关的核心价值 作为微服务架构的流量入口,网关承担着 路由转发、流量治理、安全防护 三大核心职能: 统一接入&#…...
Spark-sql编程
创建子模块并添加依赖 在IDEA中创建一个名为Spark-SQL的子模块。 在该子模块的pom.xml文件中添加Spark-SQL的依赖,具体依赖为org.apache.spark:spark-sql_2.12:3.0.0。 编写Spark-SQL测试代码 定义一个User case class,用于表示用户信息…...
K8s 生产落地
深夜收到报警短信,集群突然宕机——这可能是每个运维人最不愿面对的噩梦。生产级Kubernetes集群的部署,远不是几条命令就能搞定的事情。本文将结合真实踩坑经验,从零拆解一个高可用、高安全、可自愈的Kubernetes生产环境该如何落地。 一、架…...
SnailJob:分布式环境设计的任务调度与重试平台!
背景 近日挖掘到一款名为“SnailJob”的分布式重试开源项目,它旨在解决微服务架构中常见的重试问题。在微服务大行其道的今天,我们经常需要对某个数据请求进行多次尝试。然而,当遇到网络不稳定、外部服务更新或下游服务负载过高等情况时,请求…...
通过WebRTC源码入门OpenGL ES
文章目录 基本概念Vertex和Fragment着色器程序 准备工作getUniformLocation/getAttribLocationglVertexAttribPointer 开始绘制Demo实现 OpenGL SE是一套适用于嵌入式设备的图形API,本文主要介绍如何通过OpenGL SE在Android设备上进行图形绘制,同时我会通…...