深入理解设计模式-结构型之适配器
适配器模式(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模块内…...
【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 已经不再维护…...
2023年国赛数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...
⛳ Java 反射
目录 ⛳ Java 反射🎨 一、反射概述**🎃 使用反射的前提条件: **🎲 类正常加载过程如下图:反射优缺点:🧸 Java反射机制提供的功能: **🥅 反射主要API** 🏭 二、反射的使用Ἲ…...
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、带商城购物功能...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
