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

【设计模式】适配器模式(结构型)⭐⭐⭐

文章目录

  • 1.概念
    • 1.1 什么是适配器模式
    • 1.2 优点与缺点
  • 2.实现方式
    • 2.1 类适配器模式
    • 2.2 对象适配器模式
  • 3 Java 哪些地方用到了适配器模式
  • 4 Spring 哪些地方用到了适配器模式

1.概念

1.1 什么是适配器模式

简单来说,适配器模式就是作为两个不兼容接口之间的桥梁

1.2 优点与缺点

优点:
1.可以让原本接口不兼容的类可以合作无间。
2.增加了类的透明性和复用性,现有的系统不改变的前提下引进新的接口。
3.灵活性好,可以通过配置文件来更换适配器。
4.系统可以更易于扩展。
缺点:
1.适配器编写过程需要一定的技巧,如果接口差异过大,适配器编写会非常复杂。
2.增加系统的理解与设计难度,由于适配器模式将一些简单的接口转换成复杂的接口,增加阅读难度。

2.实现方式

2.1 类适配器模式

类适配器模式通过多重继承来实现,它同时继承了目标接口和被适配者的类。这样,适配器就可以在继承自被适配者的类的基础上,实现目标接口。

// Lightning接口
public interface Lightning {void chargeLightning();
}// Lightning充电器
public class LightningCharger implements Lightning {@Overridepublic void chargeLightning() {System.out.println("Charging via Lightning connector.");}
}// MicroUSB接口
public interface MicroUSB {void chargeMicroUSB();
}// 类适配器
public class MicroUSBClassAdapter extends LightningCharger implements MicroUSB {@Overridepublic void chargeMicroUSB() {// 直接使用继承自LightningCharger的方法System.out.println("Class Adapter converts MicroUSB to Lightning.");this.chargeLightning();}
}// 使用类适配器模式
public class AdapterDemo {public static void main(String[] args) {MicroUSBClassAdapter microUSBClassAdapter = new MicroUSBClassAdapter();microUSBClassAdapter.chargeMicroUSB();}
}

2.2 对象适配器模式

对象适配器模式通过组合来实现,它持有一个被适配者的实例,并在适配器中实现目标接口。适配器将目标接口的调用转发给被适配者的相应方法。

// Lightning接口
public interface Lightning {void chargeLightning();
}// Lightning充电器
public class LightningCharger implements Lightning {@Overridepublic void chargeLightning() {System.out.println("Charging via Lightning connector.");}
}// MicroUSB接口
public interface MicroUSB {void chargeMicroUSB();
}// 对象适配器
public class MicroUSBObjectAdapter implements MicroUSB {private Lightning lightning;public MicroUSBObjectAdapter(Lightning lightning) {this.lightning = lightning;}@Overridepublic void chargeMicroUSB() {// 适配器将MicroUSB充电请求转换为Lightning充电System.out.println("Object Adapter converts MicroUSB to Lightning.");lightning.chargeLightning();}
}// 使用对象适配器模式
public class AdapterDemo {public static void main(String[] args) {LightningCharger lightningCharger = new LightningCharger();MicroUSBObjectAdapter microUSBObjectAdapter = new MicroUSBObjectAdapter(lightningCharger);microUSBObjectAdapter.chargeMicroUSB();}
}

对象适配器模式更加灵活,因为它可以在运行时改变被适配者的实例,而类适配器模式则在编译时就已经确定了被适配者的类。

3 Java 哪些地方用到了适配器模式

JDBC(Java Database Connectivity): JDBC使用适配器模式来连接不同的数据库。DriverManager类充当适配器,它根据URL选择合适的Driver实现,并将JDBC调用转换为特定数据库的调用。
AWT(Abstract Window Toolkit)事件监听器: AWT使用适配器模式来处理事件。例如,AWTEventMulticaster类充当适配器,它将事件源的事件转发给事件监听器。
Java I/O: Java的I/O库中使用了适配器模式来适配不同的数据源和数据目的地。例如,InputStreamReader和OutputStreamWriter类充当适配器,它们将字节流转换为字符流。
Java Collections Framework: Java集合框架中使用了适配器模式来适配不同的集合类型。例如,Collections.synchronizedCollection方法返回一个线程安全的集合视图,它充当适配器,将非线程安全的集合适配为线程安全的集合。
Java XML解析: Java中解析XML时,可以使用适配器模式来适配不同的XML解析器。例如,SAXParserFactory和DocumentBuilderFactory类充当适配器,它们根据配置选择合适的解析器实现。
Java RMI(Remote Method Invocation): Java RMI中使用了适配器模式来适配远程对象和本地对象。RMI系统提供的代理类充当适配器,它将远程方法调用转换为本地方法调用。
第三方库和框架: 许多第三方库和框架也使用适配器模式来集成不同的技术或API。例如,Spring框架中的AopProxy类充当适配器,它将AOP(面向切面编程)的调用转换为目标对象的调用。

4 Spring 哪些地方用到了适配器模式

AOP(面向切面编程): Spring AOP使用适配器模式来实现方法拦截。Spring的AopProxy类充当适配器,它根据配置创建代理对象,并在目标对象的方法调用前后执行增强代码。
事件发布: Spring的事件驱动模型使用适配器模式来解耦事件的生产者和消费者。ApplicationEventMulticaster类充当适配器,它将事件发布给所有注册的监听器。
事务管理: Spring的事务管理器使用适配器模式来适配不同的事务API。例如,PlatformTransactionManager接口及其各种实现(如DataSourceTransactionManager和JtaTransactionManager)充当适配器,它们将Spring的事务抽象转换为具体的事务处理逻辑。
数据访问: Spring的数据访问模板(如JdbcTemplate、HibernateTemplate等)使用适配器模式来适配不同的数据访问技术。这些模板类充当适配器,它们将Spring的数据访问抽象转换为具体的数据库操作。
Web集成: Spring的Web模块使用适配器模式来集成不同的Web框架。例如,DispatcherServlet充当适配器,它将HTTP请求转换为Spring MVC框架的调用。
资源访问: Spring的ResourceLoader和Resource接口使用适配器模式来抽象不同类型的资源访问。ResourceLoader的实现类充当适配器,它们将资源访问的调用转换为具体文件系统、类路径或URL的访问。
消息服务: Spring的JMS(Java消息服务)集成使用适配器模式来适配不同的消息中间件。JmsTemplate和JmsListenerContainerFactory类充当适配器,它们将Spring的消息抽象转换为具体的消息中间件操作。

相关文章:

【设计模式】适配器模式(结构型)⭐⭐⭐

文章目录 1.概念1.1 什么是适配器模式1.2 优点与缺点 2.实现方式2.1 类适配器模式2.2 对象适配器模式 3 Java 哪些地方用到了适配器模式4 Spring 哪些地方用到了适配器模式 1.概念 1.1 什么是适配器模式 简单来说,适配器模式就是作为两个不兼容接口之间的桥梁。 1.…...

云原生周刊:Gateway API v1.1 发布 | 2024.6.3

开源项目推荐 Grafana Tanka Tanka 是 Grafana 开发的一款用于 Kubernetes 的灵活、可重用和简洁的配置工具,是使用 YAML 进行 Kubernetes 配置的一种替代方案。 pv-migrate pv-migrate 是一个 CLI 工具/kubectl 插件,可以轻松地将一个 Kubernetes PersistentVo…...

KotlinConf 2024:深入了解Kotlin Multiplatform (KMP)

KotlinConf 2024:深入了解Kotlin Multiplatform (KMP) 在近期的Google I/O大会上,我们推荐了Kotlin Multiplatform (KMP)用于跨移动、网页、服务器和桌面平台共享业务逻辑,并在Google Workspace中采用了KMP。紧接着,KotlinConf 2…...

探索ChatGPT-4在解决化学知识问题上的研究与应用

1. 概述 近年来,人工智能的发展主要集中在 GPT-4 等大型语言模型上。2023 年 3 月发布的这一先进模型展示了利用广泛知识应对从化学研究到日常问题解决等复杂挑战的能力。也开始进行研究,对化学的各个领域,从化学键到有机化学和物理化学&…...

性能狂飙:SpringBoot应用优化实战手册

在数字时代,速度就是生命,性能就是王道!《极速启航:SpringBoot性能优化的秘籍》带你深入SpringBoot的内核,探索如何打造一个飞速响应、高效稳定的应用。从基础的代码优化到高级的数据库连接池配置,再到前端…...

Github上一款开源、简洁、强大的任务管理工具:Condution

Condution 是一款开源任务管理工具,它以简洁易用、功能强大著称。它旨在为用户提供一个简单高效的平台,帮助他们管理日常任务、提高工作效率。 1. Condution 的诞生背景 现如今,市面上存在着许多任务管理软件,但它们往往价格昂贵…...

LeetCode-2938. 区分黑球与白球【贪心 双指针 字符串】

LeetCode-2938. 区分黑球与白球【贪心 双指针 字符串】 题目描述:解题思路一:贪心解题思路二:一次遍历统计1的个数,找0后累加左边的1的个数解题思路三: 题目描述: 桌子上有 n 个球,每个球的颜色…...

深度神经网络——什么是扩散模型?

1. 概述 在人工智能的浩瀚领域中,扩散模型正成为技术创新的先锋,它们彻底改变了我们处理复杂问题的方式,特别是在生成式人工智能方面。这些模型基于高斯过程、方差分析、微分方程和序列生成等坚实的数学理论构建。 业界巨头如Nvidia、Google…...

有代码冗余的检查工具嘛

是的,有一些代码质量工具可以帮助检查冗余代码。这些工具可以分析代码库,并识别出重复、冗余或不必要的代码片段。一些流行的代码质量工具包括: PMD: PMD 是一个开源的静态代码分析工具,支持多种编程语言,包括 Java、…...

3D培训大师:快速输出标准3D课件,打造沉浸式培训体验

随着技术的日新月异和市场的迅猛扩张,企业对员工专业技能培训的需求日益凸显。传统的培训方式往往依赖于实地操作、现场指导,这不仅需要大量的人力、物力和时间成本,而且存在安全风险。特别是化工、机械制造等行业,实操培训的成本…...

Python接口自动化测试:Json 数据处理实战

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 上一篇说了关于json数据处理,是为了断言方便,这篇就带各位小伙伴实战一下…...

Java概述 , Java环境安装 , 第一个Hello World

环境变量,HelloWorld 1.会常用的dos命令 2.会安装java所需要的环境(jdk) 3.会配置java的环境变量 4.知道java开发三步骤 5.会java的入门程序(HelloWorld) 6.会三种注释方式 7.知道Java入门程序所需要注意的地方 8.知道println和print的区别第一章 Java概述 1.1 JavaSE体系介绍…...

查看Linux端口占用和开启端口命令

查看端口的使用的情况 lsof 命令 比如查看80端口的使用的情况 lsof -i tcp:80列出所有的端口 netstat -ntlp查看端口的状态 /etc/init.d/iptables status开启端口以开启端口80为例。 1 用命令开启端口 iptables -I INPUT -p tcp --dport 80 -j accpet --写入要开放的端口/…...

24-unittest简介

一、unittest简介 unittest是Python中常用的单元测试框架,与Java中的Junit单元测试框架类似。 二、示例程序 1)导入unittest模块 import unittest 2)使用help()函数查看源码中的示例程序 help(unittest) Simple usage:import unittestc…...

Kotlin 中,扩展函数(Extension Functions)

在 Kotlin 中,扩展函数(Extension Functions)是用于向已有的类添加新功能而无需继承或使用装饰模式的一个特性。这允许你通过更自然的语法为现有类型添加方法。 下面是一个简单的扩展函数示例: // 定义一个扩展函数,…...

堪称2024最强的前端面试场景题,让419人成功拿到offer

前言 2024年的秋季招聘还有两个月就即将到来,很多同学开始思考前端面试中场景题的重要性。这里我提供一些见解和建议来帮助大家准备即将到来的面试。 首先,理解面试中场景题的必要性是至关重要的。与算法或理论问题不同,场景题更贴近实际工…...

使用node将页面转为pdf?(puppeteer实现)

本文章适合win系统下实验(linux,mac可能会出现些莫名其妙的bug我也不会解决) 具体过程 首先了解什么时无头浏览器启动无头浏览器打开指定的url页面设置导出pdf格式开始转化完整基础代码 首先了解什么时无头浏览器 没有界面的浏览器下载pupp…...

龙迅#LT8711H支持TYPE-C/DP/EDP转HDMI功能应用,分辨率支持 1080p@60Hz,芯片内置固件!

1. 概述 LT8711H是一款高性能 Type-C/DP1.2/EDP 转 HD-DVI1.3 转换器,设计用于将 USB Type-C 源或 DP1.2 源连接到 HD-DVI1.3 接收器。 该LT8711H集成了符合 DP1.2 标准的接收器和符合 HD-DVI1.3 标准的发射器。此外,还包括两个用于 CC 通信的 CC 控制器…...

WPF中Ignorable

在WPF中,“Ignorable”这个概念主要与XAML解析和标记扩展有关。当WPF的XAML解析器遇到一个它不认识的元素或属性时,它会抛出一个异常,这是因为默认情况下,WPF要求所有XAML都是完全可识别和可解析的。然而,在某些情况下…...

系统安全及应用11

一个新的服务器到手之后,部署服务器的初始化 1、配置IP地址 网关 dns解析(static)内网和外网 2、安装源外网(在线即可),内网(只能用源码包编译安装) 3、磁盘分区,lvm …...

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

【HTTP三个基础问题】

面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...