设计模式-适配器模式(Adapter)
设计模式-适配器模式(Adapter)
- 一、适配器模式概述
- 1.1 什么是适配器模式
- 1.2 简单实现适配器模式
- 1.3 使用适配器模式注意事项
- 二、适配器模式的用途
- 三、实现适配器模式的方式
- 3.1 继承适配器模式(Inheritance Adapter)
- 3.2 组合适配器模式(Composition Adapter)
- 3.3 装饰器适配器模式(Decorator Adapter)
- 3.4 代理适配器模式(Proxy Adapter)
一、适配器模式概述
1.1 什么是适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它主要用于解决两个不兼容的接口之间的问题。这种模式通过结合两个独立接口的功能,使原本不能一起工作的那些类可以一起工作。
适配器模式涉及到一个单一的类,这个类负责将独立的或不兼容的接口功能整合到一起。举个例子,读卡器就是作为内存卡和笔记本之间的适配器。我们先把内存卡插入读卡器,再把读卡器插入笔记本,然后就可以通过笔记本来读取内存卡的内容了。
适配器模式也被称为Wrapper(包装器),因为它主要是将目标类用一个新类包装一下,即在客户端与目标类之间加了一层。这解决了现存的类提供的接口与我们系统的接口不兼容,而我们还不能修改现存类的问题。
1.2 简单实现适配器模式
首先,我们定义一个目标接口Target:
public interface Target {void request();
}
然后,我们创建一个实现了Target接口的具体类ConcreteTarget:
public class ConcreteTarget implements Target {@Overridepublic void request() {System.out.println("ConcreteTarget 的 request 方法被调用");}
}
接下来,我们创建一个需要适配的接口Adaptee:
public interface Adaptee {void specificRequest();
}
然后,我们创建一个实现了Adaptee接口的具体类ConcreteAdaptee:
public class ConcreteAdaptee implements Adaptee {@Overridepublic void specificRequest() {System.out.println("ConcreteAdaptee 的 specificRequest 方法被调用");}
}
现在,我们需要创建一个适配器类Adapter,它也实现了Target接口,并包含一个Adaptee类型的成员变量。在Adapter类的request方法中,我们将调用Adaptee的specificRequest方法:
public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {System.out.println("Adapter 的 request 方法被调用");adaptee.specificRequest();}
}
最后,我们在客户端代码中使用适配器模式:
public class Client {public static void main(String[] args) {Adaptee adaptee = new ConcreteAdaptee();Target target = new Adapter(adaptee);target.request();}
}
运行客户端代码,输出结果如下:
Adapter 的 request 方法被调用
ConcreteAdaptee 的 specificRequest 方法被调用
1.3 使用适配器模式注意事项
在使用适配器模式时,需要注意以下几点:
-
1、适配器模式主要解决现有接口无法改变的问题。也就是说,适配器不是在详细设计阶段添加的,而是在解决正在运行的项目问题时使用的。
-
2、由于Java是单继承机制,类适配器需要继承src类,这一点算是一个缺点。因为这意味着目标类必须是接口,这就给设计带来了一定的局限性。
-
3、src类的方法在Adapter中都会暴露出来,这可能会增加使用的成本。
-
4、尽管适配器模式可以解决一些兼容性问题,但如果没有合理使用,可能会导致系统复杂性增加。因此,在使用时需要权衡利弊,尽量避免过度使用。
-
5、当适配器的任何方法被调用时,它会将参数转换为合适的格式,然后将调用定向到其封装对象中的一个或多个方法。因此,正确实现适配器模式对于保证代码的稳定运行至关重要。
二、适配器模式的用途
适配器模式主要应用于解决系统需要使用现有类,但这些类的接口不符合系统的需要,即接口不兼容的问题。以下是一些具体的应用场景:
-
1、系统需要使用现有的类,而此类的接口不符合系统的需要,即接口不兼容。例如,你可能需要将一个现有的类(如某个第三方库中的类)与你自己的代码一起使用,但这个现有类的接口与你所需要的接口不匹配。这时,你可以创建一个适配器类,将现有的类适配到你所需要的接口。
-
2、如果你想建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。例如,你可能需要开发一个通用的数据处理模块,该模块应该能够处理多种不同类型的数据源(如数据库、文件、网络等)。这时,你可以创建一个适配器类,将不同的数据源适配到你的数据处理模块所期望的接口。
-
3、需要一个统一的输出接口,而输入端的类型不可预知。例如,你可能需要编写一个函数,该函数接受一个对象作为参数,并调用该对象的某个方法。但是,该方法的参数类型和返回值类型可能有很多种可能性。这时,你可以创建一个适配器类,将不同的参数类型和返回值类型适配到你所需要的接口。
-
4、当需增加客户端与目标类之间的抽象层以控制对目标类的访问。这种情况下,适配器模式可以为客户端提供一个与目标类更为友好的接口。
三、实现适配器模式的方式
3.1 继承适配器模式(Inheritance Adapter)
通过继承原有的类,实现适配器功能。这种方式适用于接口不兼容的情况,但需要修改原有类的代码。
public class Adaptee {public void specificRequest() {System.out.println("Adaptee specific request");}
}public class Adapter extends Adaptee {@Overridepublic void request() {super.specificRequest();}
}
3.2 组合适配器模式(Composition Adapter)
通过组合的方式实现适配器功能。这种方式适用于接口不兼容的情况,且不需要修改原有类的代码。
public interface Target {void request();
}public class Adaptee {public void specificRequest() {System.out.println("Adaptee specific request");}
}public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}
3.3 装饰器适配器模式(Decorator Adapter)
通过装饰器模式实现适配器功能。这种方式适用于接口不兼容的情况,且不需要修改原有类的代码。
public interface Target {void request();
}public class Adaptee {public void specificRequest() {System.out.println("Adaptee specific request");}
}public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}
3.4 代理适配器模式(Proxy Adapter)
通过代理模式实现适配器功能。这种方式适用于接口不兼容的情况,且不需要修改原有类的代码。
public interface Target {void request();
}public class Adaptee {public void specificRequest() {System.out.println("Adaptee specific request");}
}public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}
相关文章:
设计模式-适配器模式(Adapter)
设计模式-适配器模式(Adapter) 一、适配器模式概述1.1 什么是适配器模式1.2 简单实现适配器模式1.3 使用适配器模式注意事项 二、适配器模式的用途三、实现适配器模式的方式3.1 继承适配器模式(Inheritance Adapter)3.2 组合适配器…...
react:创建项目
一: 使用create-react-app // 默认创建reactjs的webpack打包项目 npm i create-react-app -g create-react-app 项目名// 创建ts项目打包项目 sudo npx create-react-app my-app --template typescript 二: 使用vite npm create vitelatest // 创建react…...
RabbitMQ集群
RabbitMQ概述 1.RabbiMQ简介 RabbiMQ是⽤Erang开发的,集群⾮常⽅便,因为Erlang天⽣就是⼀⻔分布式语⾔,但其本身并不⽀持负载均衡。支持高并发,支持可扩展。支持AJAX,持久化,用于在分布式系统中存储转发消…...
Qt QtCreator调试Qt源码配置
目录 前言1、编译debug版Qt2、QtCreator配置3、调试测试4、总结 前言 本篇主要介绍了在麒麟V10系统下,如何编译debug版qt,并通过配置QtCreator实现调试Qt源码的目的。通过调试源码,我们可以对Qt框架的运行机制进一步深入了解,同时…...
JavaScript如何实现钟表效果,时分秒针指向当前时间,并显示当前年月日,及2024春节倒计时,源码奉上
本篇有运用jQuery,记得引入jQuery库,否则不会执行的喔~ <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> <meta name"chenc" content"Runoob"> <met…...
重生奇迹MU套装大全中的极品属性
在重生奇迹MU之中,你不能如其他游戏一般只看攻击与防御,你更要看属性,这才是重生奇迹中的王道!属性好,才是极品,属性不佳,即便攻击、防御再出色,也只能沦落成为一件替用品࿰…...
用Python解决猴子分桃问题
1 问题 海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中…...
YOLOv8-Seg改进:分割注意力系列篇 | 新型的多尺度卷积注意力(MSCA)模块
🚀🚀🚀本文改进: 新型的多尺度卷积注意力(MSCA)模块,实现创新,MSCA包含三个部分:深度卷积聚合局部信息,多分支深度条卷积捕获多尺度上下文,以及11卷积建模不同通道之间的关系。 🚀🚀🚀MSCA多尺度特性在小目标分割检测领域表现优异 🚀🚀🚀YOLOv8-seg…...
基于springboot实现致远汽车租赁平台管理系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现致远汽车租赁平台管理系统演示 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统…...
真的设计师做图只需要一个炫云客户端就够了
真的设计师做图只需要一个炫云客户端就够了,为什么这么说呢?因为炫云的这个客户端功能真的太全了,设计师想要的功能在炫云客户端上都有,而且还很多功能是免费的,非常的实用,具体有哪些功能我们一起来看看吧…...
简述 HTTP 请求的过程是什么?
HTTP(Hypertext Transfer Protocol)请求的过程可以简单地描述为客户端与服务器之间的通信交互。下面是一般的 HTTP 请求过程: 解析 URL:客户端解析目标 URL,提取出服务器的主机名(域名)和端口号…...
免root修改手机imei的技术原理是什么?如何实现的?hook吗
在过去,修改手机IMEI(International Mobile Equipment Identity)通常需要Root权限,这给用户带来了一些不便,也存在一定的安全风险。然而,近年来,一些技术爱好者提出了一种免Root修改手机IMEI的方…...
【Redis】整合使用,进行注解式开发及应用场景和击穿、穿透、雪崩的讲解
目录 一、整合 1. 为什么 2. 整合应用 ( 1 ) pom配置 ( 2 ) 所需配置 3. 注解式开发及应用场景 1. Cacheable 2. CachePut 3. CacheEvict 4. 击穿、穿透、雪崩 一、整合 1. 为什么 Redis可以与SSM项目整合,主要是为了提高项目的性能和效率。以下是整合Re…...
数据分析-numpy
numpy numpy numpy简介优点下载ndarray的属性输出数据类型routines 函数ndarray对象的读写操作ndarray的级联和切分级联切分 ndarray的基本运算广播机制(Broadcast)ndarry的聚合操作数组元素的操作numpy 数学函数numpy 查找和排序 写在最后面 简介 nump…...
【Java】云HIS云端数字医院信息平台源码
一、云HIS系统特色 • 使用简易化 即开即用,快速复制,按需开通功能模块,多机构共享机房、软件、服务器、存储设备等资源,资源利用最大化。 • 连锁集团化 可支持连锁集团化管理,1N模式,支撑运营&#x…...
Jupyter Notebook 内核似乎挂掉了,它很快将自动重启
报错原因: OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade perfo…...
Flink -- 事件时间 Watermark
1、事件时间: 指的是数据产生的时间或是说是数据发生的时间。 在Flink中有三种时间分别是: Event Time:事件时间,数据产生的时间,可以反应数据真实发生的时间 Infestion Time:事件接收时间 Processing Tim…...
Django框架简介
文章目录 Django框架介绍MVC与MVT模型MVCMTV 版本问题运行django注意事项 Django的下载与基本命令下载Django方式一:在命令界面使用pip安装方式二:使用pycharm安装 Django的基础命令命令行操作pycharm操作 Django项目命令行操作与Pycharm操作的区别应用D…...
把wpf的窗体保存为png图片
昨晚在stack overflow刷问题时看到有这个问题,今天早上刚好来尝试学习一下 stack overflow的链接如下: c# - How to render a WPF UserControl to a bitmap without creating a window - Stack Overflow 测试步骤如下: 1 新建.net frame…...
2023NOIP A层联测28-大眼鸹猫
给你两个长度为 n n n 的序列 a , b a,b a,b,这两个序列都是单调不降的。 你可以对 a a a 进行不超过 m m m 次操作,每次操作你可以选择一个 i i i 满足 1 ≤ i ≤ n 1\le i\le n 1≤i≤n,然后选择一个整数(可以是负数&…...
终极指南:ExplorerPatcher一键解决Windows 10开始菜单关闭延迟问题
终极指南:ExplorerPatcher一键解决Windows 10开始菜单关闭延迟问题 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher 你是否曾经遇到…...
SAP RFC接口改造记:避开WebService,用OData+Python实现轻量级跨系统调用
SAP RFC接口轻量化改造:用ODataPython构建跨系统调用新范式 当企业数字化进程加速,SAP系统与外部应用的集成需求呈指数级增长。传统RFC调用虽稳定但笨重,WebService方案又常受环境限制——这恰是OData协议大显身手的战场。本文将揭示如何用P…...
如何永久保存微信聊天记录?完整指南教你三步导出与分析
如何永久保存微信聊天记录?完整指南教你三步导出与分析 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCh…...
WeChatMsg终极指南:3步轻松导出微信聊天记录并生成年度报告
WeChatMsg终极指南:3步轻松导出微信聊天记录并生成年度报告 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…...
用国密SM4实现FPE格式保留加密:一个保护手机号、银行卡号的Python实战案例
用国密SM4实现FPE格式保留加密:保护敏感数据的Python实战指南 想象一下这样的场景:你的数据库里存储着用户的手机号和银行卡号,这些数据需要被严格保护,但又不能影响业务系统的正常运行。传统的加密方式会将这些信息变成一串乱码…...
别再死记硬背了!手把手教你标定三相霍尔传感器与电机电角度的映射关系
三相霍尔传感器与电机电角度标定实战指南 在无刷直流电机(BLDC)和磁场定向控制(FOC)系统中,精确获取转子位置是实现高效控制的基础。霍尔传感器作为最常用的位置检测元件,其状态与电角度的映射关系直接决定…...
Microsemi PolarFire FPGA实战:手把手教你配置PCIe IP核(从参考时钟到BAR空间)
Microsemi PolarFire FPGA实战:从零构建PCIe通信系统的完整指南 在当今高速数据交互领域,PCI Express(PCIe)已成为连接处理器与加速器的黄金标准。Microsemi PolarFire系列FPGA凭借其优异的功耗表现和可靠的传输性能,成为工业自动化、医疗成像…...
硬件实战手记:MOSFET损耗分析与选型避坑指南
1. MOSFET损耗的三大元凶 MOSFET在电路中的损耗主要来自三个方面:导通损耗、开关损耗和续流损耗。先说导通损耗,这是最好理解的——当MOSFET完全导通时,DS之间就像一个可变电阻,这个电阻就是Rdson。我实测过几十种MOSFETÿ…...
Windows PDF处理终极指南:零依赖的完整解决方案
Windows PDF处理终极指南:零依赖的完整解决方案 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 还在为Windows系统上复杂的PDF处理工具…...
终极华硕笔记本性能优化指南:3步快速配置GHelper轻量级硬件控制工具
终极华硕笔记本性能优化指南:3步快速配置GHelper轻量级硬件控制工具 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, T…...
