设计模式学习[15]---适配器模式

文章目录

  • 前言
  • 1.引例
  • 2.适配器模式
    • 2.1 对象适配器
    • 2.2 类适配器
  • 总结

前言

这个模式其实在日常生活中有点常见,比如我们的手机取消了 3.5 m m 3.5mm 3.5mm的接口,只留下了一个 T y p e − C Type-C TypeC的接口,但是我现在有一个 3.5 m m 3.5mm 3.5mm的耳机接口,那怎么让耳机和手机相连?

当然是买个转接头或者转接线,一头是 3.5 m m 3.5mm 3.5mm圆孔一头是 t y p e − c type-c typec接口。
那这里的转接头或者转接线,充当的就是适配器。我手机只有type-c的接口,现在要让 3.5 m m 3.5mm 3.5mm的插头适配 t y p e − c type-c typec,就需要这个适配器。

这篇博客就写一下适配器模式,看看在软件开发里面,什么时候用适配器,又是怎么用的适配器。

1.引例

我们日常写代码,一般都在debug版本下写,调试程序也是这样。但是我们要发布程序的时候,肯定是要release版本发布的。发布给客户的软件出现了bug,崩溃了,如何快速定位?这又不是我们VS里面一个F5开始调试就能搞定的,这时候就需要根据日志文件来判断了,说到这,其实就我近期开发的模块,日志量确实不太够,惭愧。

写日志我们通常是把他写到一个log.txt这样的文件里面去,现在定义这样的一个写日志文件操作的类
在这里插入图片描述

对于这个日志类,我们在main函数中一般可以这样用:

LogToFile* plog=new LogToFile();
plog->initfile();
plog->writetofile("向日志文件中写入一条日志");
plog->readfromfile();
plog->closefile();
delete plog;

如果程序运行很久,日志越来越多,各种模块的日志信息都往这个文件添加,就会导致日志文件过大,这时候需要将日志写到文件变成写到数据库。对于这种情况,其实就是新的设计与实现,具体类如下:
在这里插入图片描述

对于这个日志写到数据库的类,我们在main函数中一般可以这样用:

LogToDatabase* plog=new LogToDatabase();
plog->initdb();
plog->writetodb("向日志文件中写入一条日志");
plog->readfromdb();
plog->closedb();
delete plog;

上面是写日志的两种方式,我们可以看到他们的实现很不一样,一个对文件操作,一个对数据库操作。

现在考虑这种情况,数据库在某一天突然G了,可能因为网络问题导致无法和数据库连接。那上面的第二种写日志的方式似乎就用不了了,我们还得用回第一种方式,但这时候又来问题了。我们目前使用的方案是数据库方案,代码都是基于LogToDatabase类的接口,而LogToDatabase类的接口和LogToFile类又不一样,咋办?

这个就相当于我们耳机一直是用type-c连手机,突然有一天手机type-c口坏了,蓝牙坏了,我们只能用有线3.5mm接口耳机,这时候咋办?转接头呀!


2.适配器模式

在不改变老日志系统源码的情况下,通过引入适配器,将使用新日志系统的项目与老日志系统接驳起来,此时,适配器扮演一个中间人的角色,将项目中针对新日志系统的接口调用转换成对应的老日志系统的接口调用,从而达到新接口适配老接口的目的,这就是适配器模式的工作

在这里插入图片描述
在这里插入图片描述

接下来是考虑适配的实现方式了,这里适配器的实现分为两种:对象适配器类适配器

前者是通过类与类之间的组合关系,也就是一个类的定义中含有其他类型的成员变量。这种关系实现了委托机制,即成员函数把功能的实现委托给了其他类的成员函数,当然需要持有一个其他类的指针,才可以实现委托。

后者则是通过类与类之间的继承关系来实现接口的适配,适配器类和和适配者类之间是继承关系。


2.1 对象适配器

在适配器模式中,一般分为三种角色

Target(目标抽象型):该类定义所需要暴露的接口,这些接口就是调用者希望使用的接口,也就是客户端需要用到的接口。这里是指LogToDatabase类。

Adaptee(适配者类):这个类表示的是被适配的角色,通常是指老接口。需要用被适配。这里是指LogToFile类。

Adapter(适配器类):这个就是适配器了,充当转换器的作用,是适配模式的核心。这里的作用就是把客户端针对LogToDatabase类的接口调用转换成对LogToFile(旧接口)的调用。

参考一下UML类图,在对象适配器中,我们需要让适配器继承目标抽象型LogToDatabase,因为它是对外暴露的接口。
其次,适配器需要有老接口类的指针,用来调用老接口。
在这里插入图片描述

现在具体看一下代码:

在这里插入图片描述

在这个类中,我们通过在适配器类LogAdapter中定义一个LogToFile的指针,在外层暴露的initdb,writetodb等接口中,调用老的接口。这样就做到了接口的适配,用同一套对外暴露的接口,实现底层的适配。

适配器模式与装饰模式有类似的地方,两者都使用了类与类之间的组合关系,但两者的实现意图是不同的,适配器模式是将原有的接口适配成另外一个接口,而装饰模式是对原有功能的增强,而且无论装饰多少层,装饰模式的调用接口始终不发生改变。

2.2 类适配器

先看UML,这里适配器类内部不再持有旧接口的指针,而也是用继承关系来做。
在这里插入图片描述

依照UML,我们的具体代码如下:

在这里插入图片描述

这里我们对于目标类LogToDatabase使用的是公有继承,对于旧接口LogToFile类,我们使用的是私有继承。
这里public继承表示的时一种 is-a 关系,也就是通过子类产生的对象一定也是一个父类对象,子类继承了父类的接口。
但是private继承就不是这种关系了,是一种组合关系,是根据…实现出的关系。
这里我们对旧接口私有继承就表示想通过LogToFile类实现出LogAdapter的意思。

这种多重继承的方式来做类适配器,在具体代码的实现中,我们可以直接调用LogToFile接口,不再需要特定的指针。看起来好像很不错,但是实际上是不提倡用类适配器的。

从灵活性上来说,类适配器不如对象适配器,因为private继承方式限制了LogAdapter能调用的LogToFile中的接口。
假如有下面的情况:

class ParClass{....}
class LogToFile:public ParClass{....}

采用对象适配器的话,我只需要在里面定一个ParClass* m_pfile指针,这个指针可以指向任何ParClass的子类对象,有时候这个子类对象可能不止一个。但如果是多重继承,我们需要继承的就不止这一个类了。

总结

一般来说,过多使用适配器模式并不见得是一件好事,因为从表面上看,调用的是A接口,但内部被适配成了调用B接口,这比较容易让人迷惑,一般都是在开发后期不得已才使用这种设计模式。所以,在很多情况下,如果方便对系统进行重构的话,那么以重构来取代适配也许更好。但软件开发中也存在时常要发布新版本的情况,新版本也存在与老版本的兼容性问题,有时完全抛弃老版本并不现实,所以才借助适配器模式使新老版本兼容。在遗留代码的复用、类库的迁移等工作方面,适配器模式仍旧能发挥巨大的作用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Markdown如何导出Html文件Markdown文件

Markdown如何导出Html文件Markdown文件 前言语法详解小结其他文章快来试试吧☺️ Markdown 导出 HTML 👈点击这里也可查看 前言 Markdown的源文件以md为后缀。Markdown是HTML语法的简化版本,它本身不带有任何样式信息。我们所看到的Markdown网页(如&…

Python安装(新手详细版)

前言 第一次接触Python,可能是爬虫或者是信息AI开发的小朋友,都说Python 语言简单,那么多学一些总是有好处的,下面从一个完全不懂的Python 的小白来安装Python 等一系列工作的记录,并且遇到的问题也会写出&#xff0c…

JMeter + Grafana +InfluxDB性能监控 (二)

您可以通过JMeter、Grafana 和 InfluxDB来搭建一个炫酷的基于JMeter测试数据的性能测试监控平台。 下面,笔者详细介绍具体的搭建过程。 安装并配置InfluxDB 您可以从清华大学开源软件镜像站等获得InfluxDB的RPM包,这里笔者下载的是influxdb-1.8.0.x86_…

STL常用容器总结

1.Vector容器特性 vector 容器是一个长度动态改变的动态数组,既然也是数组,那么其内存是一段连续的内存,具有数组的随机存取的优点。 / 1.1.vector特性总结: 1.vector 是动态数组,连续内存空间,具有随机存取效率高的…

BBP飞控板中的坐标系变换

一般飞控板中至少存在以下坐标系: 陀螺Gyro坐标系加速度计Acc坐标系磁强计Mag坐标系飞控板坐标系 在BBP飞控板采用的IMU为同时包含了陀螺(Gyro)及加速度计(Acc)的6轴传感器,故Gyro及Acc为同一坐标系。同时…

【OAuth2系列】如何使用OAuth 2.0实现安全授权?详解四种授权方式

作者:后端小肥肠 🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: 【OAuth2系列】集成微…

鸿蒙MPChart图表自定义(六)在图表中绘制游标

在鸿蒙开发中,MPChart 是一个非常强大的图表库,它可以帮助我们创建各种精美的图表。今天,我们将继续探索鸿蒙MPChart的自定义功能,重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…

《新概念模拟电路》-电流源电路

电流源电路 本系列文章主要学习《新概念模拟电路》中的知识点。在工作过程中,碰到一些问题,于是又翻阅了模电这本书。我翻阅的是ADI出版的,西安交通大学电工中心杨建国老师编写的模电书。 本文主要是基于前文《新概念模拟电路》-三极管的基础…

Java实现下载excel模板,并实现自定义下拉框

GetMapping("excel/download")ApiOperation(value "模板下载")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…

C 实现植物大战僵尸(四)

C 实现植物大战僵尸(四) 音频稍卡顿问题,用了 SFML 三方库已优化解决 安装 SFML 资源下载 https://www.sfml-dev.org/download/sfml/2.6.2/ C 实现植物大战僵尸,完结撒花(还有个音频稍卡顿的性能问题,待…

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、方法概述 CNN-BiLSTM-Attention多输入单输出回归预测方法旨在通过融合CNN的局…

Ansible之批量管理服务器

文章目录 背景第一步、安装第二步、配置免密登录2.1 生成密钥2.2 分发公钥2.3 测试无密连接 背景 Ansible是Python强大的服务器批量管理 第一步、安装 首先要拉取epel数据源,执行以下命令 yum -y install epel-release安装完毕如下所示。 使用 yum 命令安装 an…

让css设置的更具有合理性

目录 一、合理性设置宽高 二、避免重叠情况,不要只设置最大宽 三、优先使用弹性布局特性 四、单词、数字换行处理 五、其他编码建议 平常写css时,除了遵循一些 顺序、简化、命名上的规范,让css具有合理性也是重要的一环。 最近的需求场…

【微服务】1、引入;注册中心;OpenFeign

微服务技术学习引入 - 微服务自2016年起搜索指数持续增长,已成为企业开发大型项目的必备技术,中高级java工程师招聘多要求熟悉微服务相关技术。微服务架构介绍 概念:微服务是一种软件架构风格,以专注于单一职责的多个响应项目为基…

设计模式 结构型 组合模式(Composite Pattern)与 常见技术框架应用 解析

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。通过这种模式,客户端可以一致地处理单个对象和对象组合。 在软件开发中,我们经常会遇到处理对象的层…

抢先体验:人大金仓数据库管理系统KingbaseES V9 最新版本 CentOS 7.9 部署体验

一、简介 KingbaseES 是中国人大金仓信息技术股份有限公司自主研发的一款通用关系型数据库管理系统(RDBMS)。 作为国产数据库的杰出代表,它专为中国市场设计,广泛应用于政府、金融、能源、电信等关键行业,以高安全性…

Linux驱动开发(17):输入子系统–电阻触摸驱动实验

有关电阻触摸的基础知识内容可以参考野火STM32相关教程,这里只介绍电阻触摸驱动的相关内容。与一般的微处理器 不同,本节使用的imx6ull内自带触摸屏控制器,只需要把电阻触摸屏的信号线接到对应的IO即可,通过配置imx6ull 触摸屏控制…

8、RAG论文笔记(Retrieval-Augmented Generation检索增强生成)

RAG论文笔记 1、 **研究背景与动机**2、方法概述3、RAG 模型架构3.1总体架构3.2 Generator(生成器)3.3 检索器(Retriever)3.4训练(Training)3.5**解码方法**(求近似 )3.6微调的参数 …

简易CPU设计入门:通用寄存器的读写

项目代码下载 请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 下载本项目代码 准备好了项目源代码以后,我…

【动手学电机驱动】STM32-MBD(3)Simulink 状态机模型的部署

STM32-MBD(1)安装 Simulink STM32 硬件支持包 STM32-MBD(2)Simulink 模型部署入门 STM32-MBD(3)Simulink 状态机模型的部署 【动手学电机驱动】STM32-MBD(3)Simulink 状态机模型部署…