结构型模式之适配器模式:让不兼容的接口兼容

在软件开发中,经常会遇到这样一种情况:系统的不同部分需要进行交互,但由于接口不兼容,导致无法直接使用。这时,适配器模式(Adapter Pattern)就能派上用场。适配器模式是设计模式中的结构型模式,它的目的是通过创建一个适配器类来“包装”一个不兼容的接口,使得两个接口能够兼容、协作。简单来说,适配器模式就是“转换接口”模式。

本文将深入探讨适配器模式,讲解其概念、应用场景,并展示如何在Java中实现适配器模式。

一、什么是适配器模式?

适配器模式的目标是使得原本由于接口不兼容而无法一起工作的类能够协同工作。它通过为不兼容的接口提供一个适配层,使得接口能够兼容并进行正常的交互。

定义:

适配器模式允许将一个类的接口转化为客户端希望的另一种接口,使得原本由于接口不兼容而无法一起工作的两个类可以合作无间。

分类:

  1. 对象适配器模式(Object Adapter):通过组合来实现适配,适配器持有一个被适配对象的引用,并将适配器的方法委托给该对象。
  2. 类适配器模式(Class Adapter):通过继承来实现适配,适配器类继承自原有的类或接口,并实现客户端所需要的接口。

二、适配器模式的结构

适配器模式通常包含以下几个角色:

  1. 目标接口(Target):客户端希望使用的接口。它是适配器模式中的标准接口,定义了客户端所需要的方法。
  2. 源接口(Adaptee):现有的接口,它已经实现了某些功能,但其接口无法直接与目标接口兼容。
  3. 适配器(Adapter):适配器通过实现目标接口并调用源接口的方法来“适配”源接口,使得客户端能够使用源接口的功能。
  4. 客户端(Client):通过目标接口调用适配器提供的功能,客户端通常不需要关心适配器的实现细节。

三、适配器模式的应用场景

适配器模式适用于以下几种场景:

  1. 系统需要与其他类库(或组件)交互,但这些类库或组件的接口与系统不兼容。
    • 比如,你的系统需要与一个老旧的API进行交互,但是该API的接口与现代的API标准不兼容,这时可以使用适配器模式来包装该接口。
  2. 需要为某个类的接口提供不同的实现方式,尤其是在需要复用现有代码的情况下。
    • 如果你已有一个类库的实现,而希望将其适配到不同的系统或接口,可以通过适配器模式进行调整和扩展。
  3. 不同接口之间的桥接。
    • 比如,已有一个类实现了某个接口,而你希望将这个类与另一个接口一起使用时,适配器模式能够实现两者之间的桥接。

四、适配器模式的优点和缺点

优点:

  1. 增强了类的复用性:通过适配器可以将已有类与系统兼容,使得这些类能够在系统中复用,而无需修改原有代码。
  2. 灵活性和可扩展性:适配器模式允许系统灵活地集成不同的类和组件,可以在不改变客户端代码的情况下,轻松地适配不同接口。
  3. 解耦合:客户端不需要关心适配器的实现细节,只需依赖目标接口,使得客户端与具体实现解耦。

缺点:

  1. 增加了代码的复杂度:为了实现适配器模式,通常需要创建多个类和接口,可能导致代码量增加,复杂度提升。
  2. 性能开销:适配器模式可能会引入额外的间接调用,特别是在使用对象适配器时,可能会产生一定的性能开销。

五、Java中实现适配器模式

我们通过一个实际的例子来讲解如何在Java中实现适配器模式。假设我们有一个老旧的系统,该系统需要与一个现代接口进行交互,但接口不兼容。

例子:

我们有一个现代的电源接口 Target,并且现有的老旧电源接口 Adaptee 需要适配到现代接口上。

// 目标接口,现代电源适配器需要实现该接口
interface Target {void provideElectricity(); // 提供电源
}// 源接口,老旧电源接口
class Adaptee {void oldProvideElectricity() {System.out.println("老旧电源提供电源...");}
}// 适配器类,实现目标接口,使用源接口的功能
class Adapter implements Target {private Adaptee adaptee;// 通过构造方法传入老旧电源接口public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}// 实现目标接口的方法,调用老旧电源接口的功能@Overridepublic void provideElectricity() {adaptee.oldProvideElectricity();  // 将调用转发给老旧电源接口}
}// 客户端代码,使用目标接口
public class AdapterPatternExample {public static void main(String[] args) {Adaptee oldElectricity = new Adaptee();Target modernElectricity = new Adapter(oldElectricity); // 创建适配器实例modernElectricity.provideElectricity(); // 调用现代电源接口方法}
}
解释:
  1. 目标接口(Target):现代电源接口,定义了 provideElectricity() 方法。
  2. 源接口(Adaptee):老旧电源接口,定义了 oldProvideElectricity() 方法。
  3. 适配器(Adapter):实现了目标接口(Target),并将目标方法调用转发到源接口(Adaptee)的方法上。
  4. 客户端(Client):通过目标接口来调用电源提供的方法,客户端无需关心适配器的实现。

输出结果:

老旧电源提供电源...

在这个例子中,Adapter 类通过将 Target 接口的方法委托给 Adaptee 类的方法来实现适配,解决了不兼容接口的问题。

六、总结

适配器模式是非常实用的设计模式,特别是在需要将现有系统与外部组件进行集成时。通过适配器模式,可以避免修改现有代码,从而降低系统的耦合度,提高系统的灵活性和可扩展性。

适配器模式的关键是通过适配器类来封装不兼容的接口,使得客户端能够继续使用目标接口的方法,而无需关心具体的实现细节。在实际开发中,适配器模式广泛应用于各种场景,例如,旧系统与新系统的兼容、第三方库的接口适配等。

通过实现适配器模式,我们能够更灵活地管理系统中的不同接口,减少系统间的依赖和耦合,提高系统的可维护性和扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/73332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt从入门到入土(十) -数据库操作--SQLITE

认识 数据库是用于存储、管理和检索数据的系统化集合。它是一种按照特定结构组织数据的存储方式,通过软件(数据库管理系统,DBMS)来实现数据的高效存储、查询、更新和管理。通过文件存储数据适用于少量的数据,而当拥有…

Django REST Framework中的序列化器类和视图类

序列化器类 一、Serializer序列化类 Serializer是DRF的序列化器基类,提供基本功能,使用Serializer类需要自己定义字段名称和类型。 BookSerializer(Serializer):name serializers.CharField()price serlializers.IntegerField()date serlializers.…

图像分类数据集

《动手学深度学习》-3.5-学习笔记 # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式, # 并除以255使得所有像素的数值均在0~1之间 trans transforms.ToTensor()#用于将图像数据从 PIL 图像格式(Python Imaging Library&#xff…

架构师面试(十五):熔断设计

问题 某电商平台经常需要在大促运营活动中暂停评论、退款等业务,基于服务治理的设计理念,我们需要对该电商平台微服务系统的【服务熔断】进行设计,对此下面描述中说法正确的有哪几项呢? A. 服务管控系统管理着平台中所有服务之间…

Ubuntu20.04安装运行DynaSLAM

目录 一、安装Anaconda 二、相关依赖库安装 1、boost安装 2、Eigen 3安装 3、opencv安装 4、Pangolin安装 三、配置Mask_RCNN环境 四、DynaSLAM编译 五、DynaSLAM运行 一、安装Anaconda 打开以下链接: Index of / 下载和自己系统匹配的安装包。这里下…

X86 RouterOS 7.18 设置笔记三:防火墙设置(IPV4)

X86 j4125 4网口小主机折腾笔记五:PVE安装ROS RouterOS X86 RouterOS 7.18 设置笔记一:基础设置 X86 RouterOS 7.18 设置笔记二:网络基础设置(IPV4) X86 RouterOS 7.18 设置笔记三:防火墙设置(IPV4) X86 RouterOS 7.18 设置笔记四…

从 YOLOv1 到 YOLOv2:目标检测的进化之路

引言 你有没有想过,当你用手机拍一张照片,里面的人、车、狗是怎么被自动识别出来的?这背后靠的就是目标检测技术。目标检测是计算机视觉中的一个重要领域,它不仅要回答“图片里有什么”,还要告诉你“这些东西在哪里”…

数据的存储---整型、浮点型

目录 一、整型在内存中的存储 1. 原码、反码、补码 2. 大端与小端 二、浮点数在内存中的存储 1.浮点数的存 2. 浮点数的取 3. 题目解析 一个变量的创建需要在内存中开辟空间,而开辟的空间大小是由数据类型决定的。下面我们就来讨论一下整型、浮点型在内存中的…

Java 大视界 -- Java 大数据在智能教育虚拟实验室建设与实验数据分析中的应用(132)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

⚡️Jolt -- 通过JSON配置来处理复杂数据转换的工具

简介:一个能够通过JSON配置(特定的语法)来处理复杂数据转换的工具。 比如将API响应转换为内部系统所需的格式,或者处理来自不同来源的数据结构差异。例如,将嵌套的JSON结构扁平化,或者重命名字段&#xff0…

47.全排列 II

47.全排列 II 力扣题目链接 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]]示例 2: 输入:nums [1,2,3] 输出…

centos没有ll

vi /etc/bashrc alias ll‘ls -l’ source /etc/bashrc

04 1个路由器配置一个子网的dhcp服务

前言 这是最近一个朋友的 ensp 相关的问题, 这里来大致了解一下 ensp, 计算机网络拓扑 相关基础知识 这里一系列文章, 主要是参照了这位博主的 ensp 专栏 这里 我只是做了一个记录, 自己实际操作了一遍, 增强了一些 自己的理解 当然 这里仅仅是一个 简单的示例, 实际场景…

网络空间安全(31)安全巡检

一、定义与目的 定义: 安全巡检是指由专业人员或特定部门负责,对各类设施、设备、环境等进行全面或重点检查,及时发现潜在的安全隐患或问题。 目的: 预防事故发生:通过定期的安全巡检,及时发现并解决潜在的…

在IGH ethercat主站中Domain和Entry之间的关系

在 IGH EtherCAT 主站中,“domain”(域)和 “entry”(条目)存在着紧密的关系,具体如下: 数据组织与管理方面:“domain” 是 EtherCAT 主站中用于管理和处理从站配置、数据映射和数据…

信息学奥赛一本通 1449:【例题2】魔板

题目 1449:【例题2】魔板 分析 首先注意:输入是按顺时针给出的,但我们处理时需要按正常顺序排,可以用以下代码读入 string s(8, 0); // 初始化全零字符串 cin>>s[0]>>s[1]>>s[2]>>s[3]; cin>>…

Unity开发的抖音小游戏接入抖音开放平台中的流量主(抖音小游戏接入广告)

前言:作者在进行小游戏审核版本的过程中,碰到了下列问题,所以对这个抖音小游戏接入广告研究了下。 还有就是作者的TTSDK版本号是6.2.6,使用的Unity版本是Unity2022.3.29f1,最好和作者的两个版本号保持一致,因为我发现TTSDK旧版的很多函数在新版中就已经无法正常使用了,必…

【xv6操作系统】系统调用与traps机制解析及实验设计

【xv6操作系统】系统调用与traps机制解析及实验设计 系统调用相关理论系统调用追溯系统调用实验设计Sysinfo🚩系统调用总结(结合trap机制) traptrap机制trap代码流程Backtrace实验alarm实验 系统调用 相关理论 隔离性(isolation)…

Docker文件夹上传秘籍Windows下的高效传输之道

哈喽,大家好,我是木头左! 一、理解Docker容器与Windows文件系统的差异 在深入探讨如何从 Windows 系统将文件夹及递归文件夹和文件上传到 Docker 容器之前,有必要先明晰 Docker 容器与 Windows 文件系统之间存在的本质差异。 (一)Docker 容器的文件系统特性 Docker 容…

08 | 实现版本号打印功能

提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…