Java设计模式-结构型模式-适配器模式
适配器模式
- 适配器模式
- 应用场景
- 案例
- 类适配器模式
- 对象适配器模式
- 接口适配器模式
- 适配器模式在源码中的使用
适配器模式
如图:国外插座标准和国内不同,要使用国内的充电器,就需要转接插头,转接插头就是起到适配器的作用
适配器模式,是将某个类的接口转化为客户端期望的另一个接口表示,主要的目的是解决兼容性问题,让原本不匹配不能一起工作的两个类可以协同工作
应用场景
-
集成旧系统:当引入新系统时,通常需要与现有的旧系统进行集成。适配器模式可以帮助将新系统的接口适配成旧系统所期望的接口,从而实现两个系统之间的兼容性。例如,将新的支付系统接口适配成与旧的支付系统兼容的接口。
-
类库适配:当使用第三方类库时,有时需要将其接口适配成符合自己项目需求的接口。适配器模式可以用来封装第三方类库的接口,使其与项目代码无缝集成。例如,将不同数据库操作类库的接口适配成统一的数据库操作接口。
-
跨平台兼容:在跨平台开发中,不同平台可能有不同的接口和实现方式。适配器模式可以帮助将不同平台的接口适配成统一的接口,从而提供跨平台的兼容性。例如,将移动应用在不同操作系统上的界面适配成统一的用户界面。
-
日志记录器:在应用中使用不同的日志记录库时,可以使用适配器模式将它们的接口适配成统一的接口,以便在应用中无缝切换不同的日志记录库。
-
第三方API集成:当与第三方API进行集成时,可能需要将第三方API的接口适配成符合自己应用的接口规范。适配器模式可以帮助实现与第三方API的集成,并提供统一的接口给应用程序使用。
适配器模式有三种实现方式:类适配器模式、对象适配器模式、接口适配器模式
案例
已知家用电是220V的交流电,类如下,可以提供220V的电压
public class HouseholdElectricity220V {/*** 输出220V电压* @return*/public int output220V(){return 220;}
}
而我的手机需要使用5V的直流电,设立目标接口
public interface MobileElectricity {int output5V();int output10V();
}
我的需求是:我要给手机充电!
那么有两条路可以选择:
- 我去和供电站商量,开一条5V直流电的通路,我直接连上充电
- 我开发一个适配器,把220V电压转为手机需要的5V直流电
很明显,只能使用方法2,开发一个适配器。
通过上述案例,应该可以体会到什么场景下需要使用适配器模式了 - 原始接口复杂且稳定,且与新需求有关联。可以通过适配器模式简化开发
- 新的需求需要兼容老的需求
不废话了
下面分别使用 类适配器模式、对象适配器模式、接口适配器模式 实现该电源适配器
类适配器模式
类适配器模式就是 通过继承 被适配者类 ,来实现适配器兼容
适配器实现如下:
public class MobileAdapter5VClass extends HouseholdElectricity220V implements MobileElectricity{@Overridepublic int output5V() {super.output220V();/*变压操作*/System.out.println("开始变压220V->5V");System.out.println("输出5V");return 5;}@Overridepublic int output10V() {super.output220V();/*变压操作*/System.out.println("开始变压220V->10V");System.out.println("输出10V");return 10;}
}
通过继承 被适配的 类,将被适配类和目标接口关联起来
测试代码如下:
/*** 类适配器模式*/
@Test
public void adapterClassTest(){MobileAdapter5VClass adapter = new MobileAdapter5VClass();adapter.output5V();
}
输出:
输出220V电压
开始变压220V->5V
输出5V
因为依赖类的继承来实现,自然耦合性较高,违反了合成复用原则(尽量多使用组合、聚合,少使用继承)
想要降低耦合性,就要使用组合的方式,实现适配器,即:对象适配器模式
对象适配器模式
通过聚合 被适配的类 来实现 适配器
直接看代码:
public class MobileAdapter5VObject implements MobileElectricity{private final HouseholdElectricity220V electricity220V;public MobileAdapter5VObject(HouseholdElectricity220V householdElectricity220V) {this.electricity220V = householdElectricity220V;}@Overridepublic int output5V() {electricity220V.output220V();/*变压操作*/System.out.println("开始变压220V->5V");System.out.println("输出5V");return 5;}@Overridepublic int output10V() {electricity220V.output220V();/*变压操作*/System.out.println("开始变压220V->10V");System.out.println("输出10V");return 10;}
}
/*** 对象适配器模式*/
@Test
public void adapterObjectTest(){HouseholdElectricity220V electricity220V = new HouseholdElectricity220V();MobileAdapter5VObject adapter = new MobileAdapter5VObject(electricity220V);adapter.output5V();
}
输出:
输出220V电压
开始变压220V->5V
输出5V
看到这里,大家应该发现一个问题,我的目标接口有两个方法,output5V() 和 output10V()
而 output5V() 才是我本次需求所需要的,但是因为接口的限制,在实现适配器的时候,又不得不重写
output10V() 方法。这样的代码一点也不优雅,而且封装性不好。
有什么解决办法呢?
想一想,上一步我们把被适配 类 和 适配器类进行了解耦,那么能不能把 目标接口 和适配器也解耦呢
所以 就有了 接口适配器模式
可以使用抽象类 先继承 目标接口,并重写接口方法为空方法。适配器只和抽象类交互,只实现自己需要的方法。
接口适配器模式
接口的适配器是这样的:接口中往往有多个抽象方法,但是我们写该接口的实现类的时候,必须实现所有这些方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些.
当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法。而此时我们只需要继承该抽象类即可
直接看代码:
/**
* 抽象适配器类
*/
public abstract class AbsMobileAdapter implements MobileElectricity{@Overridepublic int output5V() {throw new RuntimeException("请先重写");}@Overridepublic int output10V() {throw new RuntimeException("请先重写");}
}/*********************************************************************************/
/*** 接口适配器类**/
public class MobileAdapter5VInterface extends AbsMobileAdapter{private final HouseholdElectricity220V electricity220V;public MobileAdapter5VInterface(HouseholdElectricity220V electricity220V) {this.electricity220V = electricity220V;}@Overridepublic int output5V() {electricity220V.output220V();/*变压操作*/System.out.println("开始变压220V->5V");System.out.println("输出5V");return 5;}
}
适配器模式在源码中的使用
- JDBC驱动程序:不同的数据库提供商实现了不同的JDBC驱动接口,使用适配器模式可以将这些不同的接口适配为标准的JDBC接口,提高应用程序的可移植性。
- 日志框架:Java中有多个常用的日志框架,如Log4j、SLF4J等,不同的日志框架提供的API不同,使用适配器模式可以将这些不同的API适配为一个统一的接口,方便再程序中进行日志记录和管理。
- 第三方库或SDK:在使用第三方库或 SDK 时,可能由于它们实现的 API 不同而导致应用程序复杂,使用适配器模式可以将不同的 API 适配为统一的接口,简化应用程序的调用。
相关文章:

Java设计模式-结构型模式-适配器模式
适配器模式 适配器模式应用场景案例类适配器模式对象适配器模式接口适配器模式适配器模式在源码中的使用 适配器模式 如图:国外插座标准和国内不同,要使用国内的充电器,就需要转接插头,转接插头就是起到适配器的作用 适配器模式&…...

CCF编程能力等级认证GESP—C++4级—样题1
CCF编程能力等级认证GESP—C4级—样题1 单选题(每题 2 分,共 30 分)判断题(每题 2 分,共 20 分)编程题 (每题 25 分,共 50 分)第一题 绝对素数第二题 填幻方 参考答案单选题判断题编程题1编程题…...

Git用pull命令后再直接push有问题
在gitlab新建一个项目,然后拉取到本地,用: git init git pull <远程主机名> 然后就是在本地工作区增加所有文件及文件夹。再添加、提交,都没问题: 但是,git push出问题: 说明本地仓库和…...

C语言不可不敲系列:跳水比赛排名问题
目录 1题干: 2解题思路: 3代码: 4运行结果: 5总结: 1题干: 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果 A选手说:B第二,我第三; B选手说:我第二,E第四&am…...

Python与ArcGIS系列(二)获取地图文档
目录 0 简述1 获取当前地图文档2 获取磁盘中的地图文档3 获取地图文档的图层0 简述 本篇开始介绍实际代码操作,即利用arcpy(python 包)执行地理数据分析、数据转换、数据管理和地图自动化。通过arcpy调用ArcGIS中任意工具,将其与其他python工具结合使用,形成自己的工作流…...

Ansible自动化部署工具-role模式安装filebeat实际案例分析
语法以及实际案例 平时我们在进行日志收集的时候,往往会在每台机器上安装filebeat,并且由于每台机器运行服务的不同,那么收集日志的配置文件也是不一样的,如何快速高效的部署filebeat以及拥有不同的配置文件就是我们要思考的问题&…...

B2B企业如何打造独立站:从策略到实施的全面指南
随着数字化转型的加速,B2B企业越来越认识到独立站的重要性。然而,如何建设一个优秀的独立站,以及如何将独立站与企业的整体战略相结合,是许多企业面临的挑战。本文将详细探讨B2B企业如何从策略到实施打造一个成功的独立站。 一、…...

JAVA 中集合取交集
日常工作 经常需要取两个数据集的交集。对常用的List 和Set集合做了一个测试 public static void main(String[] args) {List<Integer> list1 Lists.newArrayList();List<Integer> list2 Lists.newArrayList();Set<Integer> set3 Sets.newHashSet();Set&l…...

Android13 Launcher3 定制
去掉Google搜索栏 aosp/packages/apps/Launcher3/src_build_config/com/android/launcher3/BuildConfig.java 修改QSB_ON_FIRST_SCREEN为false public static final boolean QSB_ON_FIRST_SCREEN false;去掉抽屉菜单,所有应用都放到桌面 增加控制变量 aosp/pac…...

其他word转化为PDF的方式
将 Word 文档转换为 PDF 格式,除了使用 COM 自动化外,还有其他一些方法可以在 Java 中实现。这些方法通常更加可靠和跨平台。以下是一些常用的方法: 1. 使用 Apache POI 和 Apache PDFBox 这种方法涉及使用 Apache POI 库读取 Word 文档&am…...

【Axure】axure rp 导入元件库和使用,主流元件库下载使用
vant 元件库下载:Vant4 设计资源 element UI 元件库下载:element ui 设计资源 Andt Design Vue 下载设计资源:Andt Design Vue Andt Design Pro下载设计资源:Andt Design Pro Arco Design 设计资源:Arco Design …...

ISP 处理流程
#灵感# 摆烂时间太长了,感觉知识忘光光了。重新学习,常学常新。 因为公司文档都不让摘抄、截取,所以内容是工作的一些自己记录和网络内容,不对的欢迎批评指正。 1、ISP概述 ISP是Image Signal Processor 的简称,也就…...

【计算思维】少儿编程蓝桥杯青少组计算思维题考试真题及解析C
【科技素养】少儿编程蓝桥杯青少组计算思维题考试真题及解析 1.天平的左右两端分别放有一些砝码,如下图所示,右边的砝码不变,从左边最多拿走几个砝码,可以使天平左右两边平衡: A、1 B、2 C、3 D、4 2.把下面的图形…...

百望云斩获“新华信用金兰杯”ESG优秀案例 全面赋能企业绿色数字化
近年来,中国ESG蓬勃发展,在政策体系构建、ESG信披ESG投资和国际合作等方面都取得了阶段性成效,ESG生态不断完善。全社会对ESG的认识及实践也在不断深化,ESG实践者的队伍在不断发展壮大。 ESG作为识别企业高质量发展的重要指标&…...

bclinux aarch64 ceph 14.2.10 对象存储 http网关 CEPH OBJECT GATEWAY Civetweb
相关内容 bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【3】vdbench fsd 文件系统测试-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设…...

2023年亚太杯数学建模思路 - 复盘:人力资源安排的最优化模型
文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 描述 …...

【广州华锐互动】VR居家防火逃生模拟演练增强训练的真实性
VR软件开发公司广州华锐互动在消防培训领域已开发了多款VR产品,今天为大家介绍VR居家防火逃生模拟演练系统,这是一种基于虚拟现实技术的消防教育训练设备,通过模拟真实的火灾场景,让使用者身临其境地体验火灾逃生过程,…...

PaddleClas学习1——使用PPLCNet模型对车辆属性进行识别(python)
使用PPLCNet模型对车辆属性进行识别 1. 配置PaddlePaddle,PaddleClas环境1.1 安装PaddlePaddle(1)创建 docker 容器(2)退出/进入 docker 容器(3) 安装验证1.2 安装python3.8(可选)1.3 安装 PaddleClas2. 模型推理2.1 下载官方提供的车辆属性模型2.2 基于 Python 预测引…...

CSS 实现新拟态(Neumorphism) UI 风格
什么是新拟态(Neumorphism) UI 风格?网上似乎还没有一个准确统一的定义。按照我个人的通俗理解,就是将界面的一部分凸起来,另一部分凹下去,形成的一种错落有致的拟物风格。代表作是乌克兰设计师 Alexander Plyuto 在各平台发布的新…...

js 深度学习(六)
立即执行函数 immediate invoked function expression 自动执行 执行完成后立即释放 (function(){var a 1,b2;console.log(ab) }()) // w3c建议 (function(a,b){return ab; })(a,b); // 可以加参数 可以有返回值表达式才能被执行符号执行,被小括号包裹的是表达式…...

【机器学习基础】机器学习的模型评估(评估方法及性能度量原理及主要公式)
🚀个人主页:为梦而生~ 关注我一起学习吧! 💡专栏:机器学习 欢迎订阅!后面的内容会越来越有意思~ 💡往期推荐: 【机器学习基础】机器学习入门(1) 【机器学习基…...

React hooks(一):useState
1.React hooks React hooks是React16.8的新特性,可以让React函数组件具有状态,并提供类似componentDidMount和componentDidUpdate等生命周期方法。 React 早期版本,类组件可以在shouldComponentUpdate中,通过判断props和state是…...

springboot集成swagger3+解决页面无法访问问题
引入依赖 pom文件引入swagger3依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency>配置启动文件 swagger使用ant_pattern_parser解析…...

mapreduce-maven--30.串联所有单词的字串
项目对象模型(Project Object Model,POM):Maven使用POM文件来描述项目的结构、依赖和构建设置。POM是一个XML文件,位于项目根目录下,并包含项目的基本信息、构建设置、依赖管理等。 依赖管理:M…...

Hive使用max case when over partition by 实现单个窗口取两个窗口的值(单个开窗函数,实际取两个窗口)
一、Hive开窗函数根据特定条件取上一条最接近时间的数据(单个开窗函数,实际取两个窗口) 针对于就诊业务,一次就诊,多个处方,处方结算时间可能不一致,然后会有多个AI助手推荐用药,会…...

2023年【北京市安全员-B证】试题及解析及北京市安全员-B证证考试
题库来源:安全生产模拟考试一点通公众号小程序 北京市安全员-B证试题及解析根据新北京市安全员-B证考试大纲要求,安全生产模拟考试一点通将北京市安全员-B证模拟考试试题进行汇编,组成一套北京市安全员-B证全真模拟考试试题,学员…...

二维码智慧门牌管理系统升级解决方案:流量监控引领服务卓越
文章目录 前言一、流量监控功能概述二、流量监控的益处三、应用案例和成功故事四、实施和支持 前言 随着科技的不断发展,二维码智慧门牌管理系统在其便捷高效的管理方式下,深受广大用户喜爱。为了更好地满足用户需求,提升服务质量࿰…...

Linux内核面试题(1)
整理了一些网上的linux驱动岗位相关面试题,如果错误,欢迎指正。 1硬件中断号和Linux内核的IRQ号它们是如何映射的? irq驱动会从dts获取硬件中断号,dts里的interrupts字段,使用gic_irq_domain_translate函数。 然后使…...

wpr -start generalprofile -start pool -filemode 这句命令具体是什么意思
注意事项: 总体而言,WPR 和 WPA 是强大的性能分析工具,通过它们,你可以深入了解系统运行时的性能特性,找出潜在问题并进行优化。 查看详细信息: wpr -start generalprofile -start pool -filemode 对应的结…...

C/CPP基础练习题多维数组,矩阵转置,杨辉三角详解
多维数组 1. 矩阵转置 输入一个数字构成的矩形, 将矩形的值进行转置后打印 输入: 第一行 正整数n(1<n<10), 表示矩阵的边长 随后输入一个矩阵 输出: 转置后的矩阵 样例输入: 3 1 2 3 4 5 6 7 8 9 样例输出: 1 4 7 2 5 8 3 6 9 2. 颈椎病治疗 最近云海学长一…...