设计模式之适配器模式(Adapter)
一、适配器模式介绍
适配器模式(adapter pattern )的原始定义是:将类的接口转换为客户期望的另一个接口,
适配器可以让不兼容的两个类一起协同工作。
适配器模式是用来做适配,它将不兼容的接口转换为可兼容的接口,让原本由于接口
不兼容而不能一起工作的类可以一起工作。适配器模式有两种实现方式:类适配器和
对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。
类适配器模式的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部
结构,所以应用相对较少些。
二、适配器模式原理
适配器模式(Adapter)包含以下主要角色:
1)目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
2)适配者(Adaptee)类:适配者即被适配的角色,它是被访问和适配的现存组件库
中的组件接口。
3)适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配
者接口转换成目标接口,让客户按目标接口的格式访问适配者。
类适配器类一般是继承 “适配者类(适配者的具体实现)” 并实现目标接口,而对象适配器
器类一般是在适配器类中引用适配者类对象;适配器模式结构图如下:
类适配器模式结构图:
对象适配器模式结构图:
三、适配器模式应用示例
以电脑目前只能读取SD卡的信息为例来看下适配器模式的使用
一台电脑目前只能读取SD卡的信息,这时我们想要使用电脑读取TF卡的内容, 就需要将TF卡
加上卡套,转换成SD卡,最后将TF卡中的内容读取出来
1、类适配器模式实现
实现方式:
类适配器类继承 “适配者类的具体实现(即TFCardImpl)” 并实现目标接口SDCard
UML类图如下:
具体代码实现如下:
/*** 类适配器* 以电脑目前只能读取SD卡的信息为例来看下适配器模式的使用* 一台电脑目前只能读取SD卡的信息,这时我们想要使用电脑读取TF卡的内容, 就需要将TF卡加上卡套,转换成SD卡** SD卡接口--目标(Target)接口*/
public interface SDCard {//读取SD卡方法String readSD();//写入SD卡功能void writeSD(String msg);
}/******************************************************** SD卡实现类*********************************************************/
public class SDCardImpl implements SDCard{@Overridepublic String readSD() {String msg = "sd card reading data";return msg;}@Overridepublic void writeSD(String msg) {System.out.println("sd card write data : " + msg);}
}/*** TF卡接口--适配者*/
public interface TFCard {//读取TF卡方法String readTF();//写入TF卡功能void writeTF(String msg);
}/******************************************************** TF卡实现类** *******************************************************/
public class TFCardImpl implements TFCard{@Overridepublic String readTF() {String msg = "tf card reading data";return msg;}@Overridepublic void writeTF(String msg) {System.out.println("tf card write data : " + msg);}
}/******************************************************** 定义适配器类,让SD卡兼容TF卡* 类适配器--通过继承来实现适配********************************************************/
public class SDAdapterTF extends TFCardImpl implements SDCard{@Overridepublic String readSD() {System.out.println("adapter read tf card ");return readTF();}@Overridepublic void writeSD(String msg) {System.out.println("adapter write tf card");writeTF(msg);}
}******************************************************** 电脑类,* 电脑类只能读取sd卡********************************************************/
public class Computer {public String read(SDCard sdCard){return sdCard.readSD();}
}//测试
public class Test {public static void main(String[] args) {Computer computer = new Computer();SDCard sdCard = new SDCardImpl();System.out.println(computer.read(sdCard));System.out.println("========================");SDAdapterTF adapterTF = new SDAdapterTF();System.out.println(computer.read(adapterTF));}
}
2、对象适配器模式实现
实现方式:
对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实
现当前系统的业务接口。
对象适配器模式UML类图如下:
代码实现:
在类适配器模式的代码基础上我们只需要修改 “适配器类” 就可以了,具体代码如下:
/******************************************************** 适配器类* 对象适配器类--通过组合的方式来实现适配********************************************************/
public class SDAdapterTF2 implements SDCard {private TFCard tfCard;public SDAdapterTF2(TFCard tfCard){this.tfCard = tfCard;}@Overridepublic String readSD() {System.out.println("adapter read tf card ");return tfCard.readTF();}@Overridepublic void writeSD(String msg) {System.out.println("adapter write tf card");tfCard.writeTF(msg);}
}
四、适配器模式总结
1、适配器模式优点
1)将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无序修改原有结构
2)增加了类的透明性和复用性,将具体业务实现过程封装在适配者类中,对于客户端类而言
是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
3)灵活性和扩展性都非常好,通过使用配置文件可以很方便的更换适配器,也可以在不修改
原有代码的基础上增加新的适配器类,符合开闭原则。
2、适配器模式缺点
2.1、类适配器的缺点
1)对于Java等不支持多重继承的语言,一次最多只能适配一个适配者类,不能同时适配
多个适配者
2)适配者类不能为最终类,即不能被关键字final修饰
2.2、对象适配器的缺点
1)与类适配器模式相比较,在该模式下要在适配器中置换适配者类的某些方法比较麻烦。
3、适配器模式适用场景
1)统一多个类的接口设计时:
某个功能的实现依赖多个外部系统(或者说类)。通过适配器模式,将它们的接口适配为
统一的接口定义
2)需要依赖外部系统时:
当我们把项目中依赖的一个外部系统替换为另一个外部系统的时候,利用适配器模式,可
以减少对代码的改动
3)原有接口无法修改时或者原有接口功能太老旧但又需要兼容时:
如JDK1.0 Enumeration 到 Iterator 的替换,适用适配器模式保留 Enumeration 类,并将
其实现替换为直接调用 Itertor
4)适配不同数据格式时:
如Slf4j 日志框架,定义打印日志的统一接口,提供针对不同日志框架的适配器
4、代理、桥接、装饰与适配4种设计模式的区别
代理、桥接、装饰器、适配器,这 4 种模式是比较常用的结构型设计模式。它们的代码结构
非常相似。但其各自的用意却不同,简单说一下它们之间的关系:
1)代理模式:
代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,
而非加强功能,这是它跟装饰器模式最大的不同。
2)桥接模式:
桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地
加以改变。
3)装饰器模式:
装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的
嵌套使用。
4)适配器模式:
将一个类的接口转换为客户希望的另一个接口。适配器模式让那些不兼容的类可以一起工作
相关文章:
设计模式之适配器模式(Adapter)
一、适配器模式介绍 适配器模式(adapter pattern )的原始定义是:将类的接口转换为客户期望的另一个接口, 适配器可以让不兼容的两个类一起协同工作。 适配器模式是用来做适配,它将不兼容的接口转换为可兼容的接口,让原本由于接口…...
[git] github管理项目之环境依赖管理
导出依赖到 requirements.txt pip install pipreqs pipreqs . --encodingutf8 --force但是直接使用pip安装不了torch,需要添加源!! pip install -r requirements.txt -f https://download.pytorch.org/whl/torch_stable.html想到一个麻烦的…...
【STM32 Blue Pill编程实例】-SD卡文件读写(SPI接口)
SD卡文件读写(SPI接口) 文章目录 SD卡文件读写(SPI接口)1、SD卡模块介绍2、硬件准备与接线3、模块配置3.1 SPI接口配置3.2 SPI接口的片选信号引脚配置3.3 FATFS配置4、代码实现在本文中,我们将介绍如何将 microSD 卡与 STM32 Blue Pill 连接,并在STM32CubeIDE中对SD卡进行…...
为什么需要软件测试?
软件测试 软件测试是评估和验证计算机程序或系统是否按预期运行的过程。 它涉及执行程序或系统以识别预期结果和实际结果之间的任何错误或差距。 目标是确保软件满足指定的要求,没有缺陷,并在不同场景中可靠地工作。 为什么需要软件测试?…...
成为超人:普通人如何白手起家,富一代和富二代的根本区别是什么?
成为超人:普通人如何白手起家,富一代和富二代的根本区别是什么? 我的问题是事业就讲 10 年装逼学习法失效① 光说不练,还是太懒真正的勤奋,解决温饱后,只专注赚钱这件事 ② 信念飘摇,随波流转万…...
Java 集合 Collection常考面试题
理解集合体系图 collection中 list 是有序的,set 是无序的 什么是迭代器 主要遍历 Collection 集合中的元素,所有实现了 Collection 的集合类都有一个iterator()方法,可以返回一个 iterator 的迭代器。 ArrayList 和 Vector 的区别? ArrayList 可以存放 null,底层是由数…...
C++继承与菱形继承(一文了解全部继承相关基础知识和面试点!)
目的减少重复代码冗余 Class 子类(派生类) : 继承方式 父类(基类) 继承方式共有三种:公共、保护、私有 父类的私有成员private无论哪种继承方式都不可以被子类使用 保护protected权限的内容在类内是可以访问,但是在…...
谷歌DeepMind 德米斯·哈萨比斯 因蛋白质预测AI荣获诺贝尔化学奖
2024年诺贝尔化学奖的一半授予了谷歌DeepMind的联合创始人兼首席执行官德米斯哈萨比斯和公司总监约翰M朱姆珀,以表彰他们在利用人工智能预测蛋白质结构方面的研究成果。另一半奖项则授予华盛顿大学生物化学教授大卫贝克,以表彰他在计算蛋白质设计领域的贡…...
内网笔记大全
内网笔记大全 1、基础命令 Windows 1、net user #查看用户 2、net view #查看在线主机 3、systeminfo #查看操作系统的基本配置 4、ipconfig /all #详细显示当前网络配置信息和网卡信息 5、net localgroup #查看本地组信息 6、net localgroup administrators #查看管理员组 7、…...
peft.LoraConfig()参数说明
LoraConfig()介绍 LoraConfig()是peft库中的一个配置类,用于设置大模型微调方法LoRA(Low-Rank Adaptation)的相关参数。PEFT 库为各种参数高效的微调方法(如 LoRA)提供了封装,以减少微调大模型时的计算资源…...
串口(UART)的FPGA设计(接收与发送模块)
目录 串口基础知识 一、什么是串口?有哪些特点? 二、常见的串口通信协议有哪些?他们有什么区别?...
JSON 格式化工具:快速便捷地格式化和查看 JSON 数据
JSON 格式化工具:快速便捷地格式化和查看 JSON 数据 为什么需要 JSON 格式化工具? 在日常开发和调试中,JSON 是非常常见的数据交换格式。无论是前端与后端的接口调用,还是数据存储和处理,JSON 格式都扮演着重要角色。…...
【星汇极客】STM32 HAL库各种模块开发之1.8TFT屏幕
前言 本人是一名嵌入式学习者,在大学期间也参加了不少的竞赛并获奖,包括:江苏省电子设计竞赛省一、睿抗机器人国二、中国高校智能机器人国二、嵌入式设计竞赛国三、光电设计竞赛国三、节能减排竞赛国三等。 暑假的时候参加了太多的比赛&#…...
Excel中使用SQL语句的四种方法
总结在 Excel 中使用 SQL 语句的四种方法,各种方法都有各自的适用场景,可以选择自己熟悉的或喜欢方式。本文以在 Excel 中操作 MS SQL 数据库的数据为例进行说明。MS SQL 的数据如下,使用微软 SQLExpress 版本。 方法 1: Excel 现…...
目标检测中的损失函数
损失函数是用来衡量模型与数据的匹配程度的,也是模型权重更新的基础。计算损失产生模型权重的梯度,随后通过反向传播算法,模型权重得以更新进而更好地适应数据。一般情况下,目标损失函数包含两部分损失,一个是目标框分…...
list库实现
list库实现的要点: 构建list类时,需要同时构建struct Node来存储节点信息,list类中只存储哨兵位节点信息,迭代器类需要template<T,Ptr,Ref>来构建const和非const迭代器,迭代器中也是存储节点信息。反向迭代器也…...
MFC工控项目实例二十三模拟量输入设置界面
承接专栏《MFC工控项目实例二十二主界面计数背景颜色改变》 1、在SenSet.h文件中添加代码 #include "BtnST.h" #include "ShadeButtonST.h"/ // SenSet dialogclass SenSet : public CDialog { // Construction public:SenSet(CWnd* pParent NULL); //…...
排序算法总结(三)希尔排序
访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。 如果你在网上搜一下希尔排序,都会告…...
如何迁移 Linux 服务器 第一部分 - 系统准备
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 在许多情况下,您可能需要将数据和操作需求从一个服务器迁移到另一个服务器。您可能需要在新的数据中心实施解决方案&a…...
网络IO模型都有哪些
“网络IO模型有BIO、NIO、AIO ” “他们分别代表什么,有什么区别吗? BIO:同步阻塞IO。 NIO:同步非阻塞IO。 AIO:异步非阻塞IO。 “BIO为什么是同步阻塞IO,他阻塞的是谁跟谁之间的关联?”。 首先…...
数据结构: 数组在算法中的应用
数组是计算机科学中的一种基础数据结构,它在算法中有着广泛的应用,其关键要素是索引与索引对应的值。 请注意,这些代码示例需要适当的辅助函数(如 swap )和主函数来运行。此外,一些算法(如KMP算…...
js快速转换时间(时间戳转换成年月日时分秒)
1:js转换 1728270833000 转换为 2024-10-07 11:13:53 var date new Date(1728270833000); // 参数需要毫秒数,所以这里将秒数乘于 1000 Y date.getFullYear() -; M (date.getMonth()1 < 10 ? 0(date.getMonth()1) : date.getMonth()1) -; D…...
LeetCode15.三数之和
题目链接:15. 三数之和 - 力扣(LeetCode) 1.常规解法(会超时) 由于这道题需要排除相同的三元组,则可以先将目标数组从小到大排序,再遍历数组找到每个符合条件的三元组,若结果中不包…...
SpringBoot3.3 优雅启停定时任务
定时任务是非常常见的功能,在一个复杂的应用程序中,如何优雅地管理这些定时任务的启动与停止尤为重要。 Spring Boot 提供了强大的任务调度支持,通过@Scheduled注解可以轻松地创建定时任务,并且可以通过配置来灵活地管理这些任务的执行环境。在本文中,我们将深入探讨如何…...
数据结构之二叉搜索树(key模型与key_value模型)
二叉搜索树(key模型与key_value模型) 1. ⼆叉搜索树的概念2. ⼆叉搜索树的性能分析3. ⼆叉搜索树的插⼊4. ⼆叉搜索树的查找5. ⼆叉搜索树的删除6. ⼆叉搜索树的实现代码7. ⼆叉搜索树key和key/value使⽤场景7.1 key搜索场景:7.2 key/value搜…...
图说几何学2300年重大错误:附着在直线z上的直线段必是z的一部分
黄小宁 用泡沫塑料和油漆制成的铅球与真正的铅球,两者有不同的内部形状。同样,数学有长度相同但内部形状不同的伪≌直线段。 几何学有史2300年来一直认定附着在直线z上的直线段一定是z的一部分。其实这是2300年肉眼直观错觉——百年病态集论的症结。 …...
汽车网关(GW)技术分析
一、引言 在现代汽车电子系统中,汽车网关(Gateway,简称 GW)扮演着至关重要的角色。随着汽车电子技术的不断发展,汽车内部的电子控制单元(Electronic Control Unit,简称 ECU)数量不断…...
Telnet命令详解:安装、用法及应用场景解析
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storm…...
C++之LIST模拟实现(代码纯享版)
目录 文章目录 前言 一、代码 总结 前言 本文主要展示了模拟List的代码实现 一、代码 #pragma once #include<iostream> #include<assert.h> using namespace std; namespace zlh {template<class T>struct list_node{T _data;list_node<T>* _next;l…...
华为OD机试 - 括号匹配 - 栈(Python/JS/C/C++ 2024 E卷 100分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…...
户外媒体网站建设免费/网推什么平台好用
对于绝大多数人来说,高三是一生之中知识水平的巅峰,但是在这里面不包括区块链的爱好者及从业者。要知道,目前区块链是属于行业的早期阶段,我们币圈和链圈的小伙伴,也将认知作为财富的象征,大家的区块链知识…...
网站开发工程师 能做什么/网站友情链接怎么添加
多元线性回归算法和正规方程解 ——燕江依/2019.08.05 1、对于多元线性回归算法,它对于数据集具有较好的可解释性,我们可以对比不过特征参数的输出系数的大小来判断它对数据的影响权重,进而对其中隐含的参数进行扩展和收集,提高整…...
有做游戏广告的网站/软文推广代表平台
SRANDMEMBER SRANDMEMBER key [count] 如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素。 从 Redis 2.6 版本开始, SRANDMEMBER 命令接受可选的 count 参数: 如果 count 为正数,且小于集合基数&am…...
新企业在哪里做网站好/关键词挖掘啊爱站网
C11 在类中引入了Move Constructor and the Move Assignmnt Operaetor,所谓‘move’指的是在复制对象时,left object 不用再创建资源,直接把right object 的资源当做自己的来用。而right object 的资源将全部被设置为default ,即为…...
海南网站建设中心/seo免费培训视频
前面我们已经搭建了前端环境,运行起来后是可以看见登录框的,但是由于后端没有写东西,不能成功登录,今天我们就完成这个功能。 一、修改登录地址到本地(模拟登录) 前篇文章已经讲过,传送门&#…...
电脑做微信推送的网站/口碑营销案例
刚刚读完了Joel的《火星人的耳机》一文,文中并非要告诉我们如何生产火星人所要使用的耳机,而是说明了一个很严重的问题,那就是有关于地球人的浏览器的问题。 当前到底有多少种浏览器供我们使用?似乎有点儿算不清楚了,最…...