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

深入理解设计模式-结构型之适配器

适配器模式(Adapter Pattern):

适配器模式用于将一个类的接口转换成另一个类的接口,以使两者能够一起工作。适配器模式通常用于处理已经存在的类让它们能够与其他类协同工作而不需要修改原始类的代码。(用于解决两个不兼容接口之间的问题。适配器允许将一个类的接口转换为客户端期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。)

主要组成部分:

  • 目标接口(Target Interface):定义客户端期望的接口。

  • 适配者(Adaptee):已经存在的类,需要被适配以满足目标接口。

  • 适配器(Adapter):实现目标接口,并在内部持有一个适配者对象,将目标接口方法调用转发给适配者。

    • 适配者(Adaptee)是一个已经存在的类,它实现的是在早期已经定义好的接口,而这个接口与你的系统中要求的目标接口(也就是客户端所期望的接口)不兼容。
    • 适配者的接口可能是一个旧的、第三方的、或者是不同版本的接口。这个接口可能已经在一些已有的类中得到了实现,但它的方法名、参数或者行为与你的系统中的目标接口不匹配。
    • 所以,为了能够在你的系统中使用这个已经存在的类,你需要创建一个适配器来将这个已有的接口适配到你的目标接口上。

适配器模式的核心思想就是通过适配器类,将适配者的接口适配成符合你的系统需求的目标接口,从而能够让这个已经存在的类能够被无缝地集成到你的系统中。

适配器模式示例:

假设有一个旧系统中的类 OldSystem,它有一个方法 oldMethod。现在我们想在新系统中使用这个方法,但新系统要求使用一个新的接口 NewInterface。

适配器模式有两种实现方式:类适配器和对象适配器。

  • 对象适配器:
    • 对象适配器使用组合来实现适配器功能。适配器类包含一个原有类的实例。
// 旧系统的类(适配者 adaptee)
class OldSystem {void oldMethod() {System.out.println("Old System Method");}
}// 新系统的接口
interface NewInterface {void newMethod();
}// 适配器类
class Adapter implements NewInterface {private OldSystem oldSystem; //适配器类包含一个原有类的实例。//构造注入public Adapter(OldSystem oldSystem) {this.oldSystem = oldSystem;}public void newMethod() {oldSystem.oldMethod();}
}// 客户端代码
public class AdapterExample {public static void main(String[] args) {OldSystem oldSystem = new OldSystem();NewInterface adapter = new Adapter(oldSystem);adapter.newMethod(); // 调用旧系统的方法,通过适配器实现新接口}
}
  • 类适配器:
    • 类适配器使用继承来实现适配器功能。适配器类继承了原有的类(Adaptee)并实现了目标接口(Target)
//适配者(旧)和接口和上面一样。
// 适配器类
class Adapter extends OldSystem implements NewInterface {public  void newMethod(){oldMethod();}
}// 客户端代码
public class AdapterExample {public static void main(String[] args) {NewInterface adapter = new Adapter();adapter.newMethod(); // 调用旧系统的方法,通过适配器实现新接口}
}

适配器类的作用是将已存在的接口适配到另一个不兼容的接口上,使得客户端代码能够通过目标接口与适配者进行交互。

应用场景

  • 集成旧系统或第三方库:当你需要使用一个已经存在的类或库,但其接口与你当前系统的其他部分不兼容时,适配器模式可以帮助你将这个类适配为符合你系统需求的接口。

  • 接口版本升级:当接口的一个新版本发布,但你的系统还在使用旧版本接口时,通过适配器模式可以兼容旧版本接口,同时适配到新版本接口上。

  • 多接口转换:当一个类需要实现多个接口,但这些接口的方法命名、参数或行为存在冲突时,可以使用适配器模式来适配这些接口,使它们能够被同一个类实现。

  • 现有类不符合需要的接口:有时你可能需要一个类来实现某个接口,但这个类并没有实现该接口。通过创建适配器类,你可以将这个类的方法适配到接口的方法上,使得类能够满足接口的要求。

  • 接口的多态性:适配器模式可以帮助你在多态性的情境中使用不同的实现,以适应不同的场景。

适配器模式的主要用途是在不改变现有类的情况下,让原本不兼容的接口能够协同工作。这在软件开发中常常遇到,特别是在集成不同模块、版本升级、对外提供兼容接口等情况下非常有用。

源码应用

  • Java IO:InputStreamReader 和 OutputStreamWriter 类将字节流适配为字符流,实现了字符流与字节流之间的适配。

  • org.springframework.web.servlet.HandlerAdapter 接口是 Spring MVC 框架中的一个关键接口,**用于将不同类型的处理器(例如控制器)适配为统一的处理方式,**以便处理请求。不同的处理器可能需要不同的适配逻辑,因此 Spring 提供了多个实现类来适应不同的处理器类型。

    • RequestMappingHandlerAdapter:这是 Spring MVC 默认使用的适配器,用于适配使用注解 @RequestMapping 的控制器方法。它支持将方法返回的数据适配为视图或其他形式。
    • WebSocketHandlerAdapter:用于适配实现了 WebSocketHandler 接口的处理器,用于处理 WebSocket 请求。
    • SimpleServletHandlerAdapter:用于适配实现了 Servlet 接口的处理器,允许你将一个 Servlet 类适配为 Spring MVC 的处理器。

这些适配器实现了相应的适配逻辑,将不同类型的处理器适配为统一的处理方式,以满足 Spring MVC 的框架要求。通过这些适配器,Spring MVC 可以在处理不同类型的请求时统一调用适当的处理器,并将处理结果适配为视图或其他响应形式。

相关文章:

深入理解设计模式-结构型之适配器

适配器模式(Adapter Pattern): 适配器模式用于将一个类的接口转换成另一个类的接口,以使两者能够一起工作。适配器模式通常用于处理已经存在的类,让它们能够与其他类协同工作,而不需要修改原始类的代码。&…...

桥梁结构健康监测系统,智能预警降低桥梁安全隐患

桥梁通常位于现代综合交通网络中的咽喉部位,对区域经济发展起着重要的推进作用,然而在为社会经济发展做出巨大贡献的同时,它们不可避免地会在荷载作用、环境侵蚀和自然灾害等影响下出现材料腐蚀劣化、结构损伤开裂、性能退化和功能失效等损伤…...

夏威夷等全球多地深陷「末日狂烧」,关键时刻 AI 监测能否跑赢野火?

内容一览:当地时间 8 月 8 日,美国夏威夷州突发野火,当地居民和游客不得不跳入太平洋中躲避火势。截至 8 月 17 日,这场野火已经造成110 人死亡,超过 1000人失踪。与此同时,美国、加拿大、法国等地也正遭遇…...

解决多模块内核心模块有接口打包成jar后被依赖并调用遇到的问题(springcloud集成ruoyi.quartz)

项目准备开发个新功能,刚好很喜欢ruoyi写的任务调度,因此想到了集成ruoyi.quartz模块 ,遇到了很多问题: 首先因为ruoyi.quartz模块依赖了ruoyi.common模块,因此第一步我需要把common模块一部分依赖项复制到了quartz模块内&#xf…...

【kubernetes系列】Kubernetes之Kubelet运行机制和状态更新机制

Kubelet运行机制 Kubelet是Kubernetes中的一个重要组件,在每个 Node 节点上都会启动 kubelet 服务。 该服务主要用于处理 Master 节点下发到本节点的任务,管理 Pod及Pod 中的容器。每个kubelet 进程会在 API Server 上注册节点自身信息,定期…...

(学习笔记-进程管理)怎么避免死锁?

死锁的概念 在多线程编程中,我们为了防止多线程竞争共享资源而导致数据错乱,都会在操作共享资源之前加上互斥锁,只有成功获得到锁的线程,才能操作共享资源,获取不到锁的线程就只能等待,直到锁被释放。 那…...

【golang】链表(List)

List实现了一个双向链表,而Element则代表了链表中元素的结构。 可以把自己生成的Element类型值传给链表吗? 首先来看List的四种方法。 MoveBefore方法和MoveAfter方法,它们分别用于把给定的元素移动到另一个元素的前面和后面。 MoveToFro…...

android平台的语音聊天助手源码

目录 1 android平台的语音聊天助手源码 1.1 //js处理工具类 1.1.1 openImage 1.2 LoadWebDetails android平台的语音聊天助手源码package com.shrimp.xiaoweirobot.net; import java.util.ArrayList;...

Python读取Word统计词频输出到Excel

1.安装依赖的包 "# 读取docx\n", "!pip install python-docx\n", "!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx\n", "# 中英文分词\n", "!pip install jieba\n", "!pi…...

windows docker mysql8.0 挂载配置文件不生效的问题

原因 mysql 8.0 遇到sql_modeonly_full_group_by的问题,于是就自定义my.cnf 去掉only_full_group_by,修改my.cnf 文件后,进行映射启动 docker run 命令 docker run -p 3306:3306 --privilegedtrue --restartalways -d --name axsc-mysql -…...

openGauss学习笔记-42 openGauss 高级数据管理-触发器

文章目录 openGauss学习笔记-42 openGauss 高级数据管理-触发器42.1 语法格式42.2 参数说明42.3 示例 openGauss学习笔记-42 openGauss 高级数据管理-触发器 触发器会在指定的数据库事件发生时自动执行函数。 42.1 语法格式 创建触发器 CREATE TRIGGER trigger_name { BEFORE…...

Leetcode33 搜索旋转排序数组

题解: /*** 旋转排序数组可分为N1 N2两个部分,如:[4,5,6,7,1,2,3],N1为[4,5,6,7],N2为[1,2,3]** 必然满足以下两个条件:* 1. N1和N2都是分别递增的;* 2. N1中的所有元素大于N2中的所有元素;** …...

docker 第一章

目录 1.安装 docker 2.镜像、容器 3.总结 1.安装 docker 2.镜像、容器 3.总结 容器在 linux 上的本机运行,与其他容器共享主机的内核。它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量级。...

注册中心 —— SpringCloud Netflix Eureka

Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务注册与发现,同时提供了负载均衡、故障转移等能力,目前 Eureka2.0 已经不再维护&#xf…...

2023年国赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...

⛳ Java 反射

目录 ⛳ Java 反射🎨 一、反射概述**🎃 使用反射的前提条件: **🎲 类正常加载过程如下图:反射优缺点:🧸 Java反射机制提供的功能: **🥅 反射主要API** 🏭 二、反射的使用&#x1f3a…...

Android 13 像Settings一样开启关闭深色模式

一.背景 由于客户定制的Settings需要开启关闭深色模式,所以需要自己调用开启关闭深色模式 二.前提条件 首先应用肯定要是系统应用,并且导入framework.jar包,具体可以参考: Android 应用自动开启辅助(无障碍)功能并使用辅助(无障碍)功能_android 自动开启无障碍服务_龚礼鹏…...

微服务实战项目-学成在线-项目优化(redis缓存优化)

微服务实战项目-学成在线-项目优化(redis缓存优化) 1 优化需求 视频播放页面用户未登录也可以访问,当用户观看试学课程时需要请求服务端查询数据,接口如下: 1、根据课程id查询课程信息。 2、根据文件id查询视频信息。 这些接口在用户未认…...

IDEA 找不到项目 ‘org.springframework.boot:spring-boot-starter-parent:3.1.2‘

找不到项目 ‘org.springframework.boot:spring-boot-starter-parent:2.6.7’ 这个问题主要是因为ide的缓存导致的,我们直接清理缓存并重启ide 重启之后ide会对pom文件进行编排索引完成之后问题就没有了...

thinkphp开发的在线学习培训考试模拟考试做题练习系统带商城功能证书管理课程系统

thinkphp开发的在线学习培训考试模拟考试做题练习系统带商城功能证书管理课程系统 1、做题界面 2、前端UI的展示 3、带商城购物功能...

MMaDA: Multimodal Large Diffusion Language Models

CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...

一些实用的chrome扩展0x01

简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...