【JAVA设计模式】适配器模式——类适配器模式详解与案例分析

news2024/9/27 9:19:27

前言

在软件设计中,适配器模式(Adapter Pattern)是一种结构型设计模式,旨在使不兼容的接口能够协同工作。它通过引入一个适配器类,帮助两个接口之间进行适配,使得它们能够互相操作。本文将详细介绍适配器模式的定义、使用场景、实现方式、接口适配器以及其优缺点。

一、适配器模式的定义

适配器模式通过引入一个适配器类,将一个类的接口转换成客户端所期望的另一种接口。适配器模式的核心在于“适配”,它允许原本由于接口不兼容而无法一起工作的类能够协同工作。

主要角色

  1. 目标接口(Target):目标接口是客户端所期望的接口,定义了客户端需要的方法。客户端代码依赖于目标接口而不是具体的实现类,这样可以使系统更加灵活和可扩展。
  2. 适配者类(Adaptee):源接口是现有的接口,它的接口与目标接口不一致。源接口包含了客户端需要的实际功能,但其接口形式无法直接被客户端使用。
  3. 适配器类(Adapter):适配器实现目标接口,并持有源接口的实例(对象适配器)或继承源接口(类适配器)。适配器通过在实现目标接口的方法中调用源接口的方法,将源接口的方法转换成目标接口的方法。

三者之间的关系

  • 客户端依赖目标接口进行编程。
  • 适配器实现了目标接口,并通过组合或继承的方式调用源接口的方法。
  • 适配器将源接口的方法适配成目标接口的方法,从而使得客户端可以无缝地使用源接口的功能。

二、适配器模式的使用场景

适配器模式适用于以下情况:

  1. 系统需要使用现有的类,但接口不符合要求:如果你有一个类,它的接口与系统的需求不匹配,可以通过适配器模式进行转换。
  2. 需要使用多个现有的类,但接口不一致:如果系统中需要整合多个不兼容的接口,可以通过适配器模式使其兼容。
  3. 系统中使用第三方库或框架:当你引入第三方库或框架时,可能会遇到接口不一致的情况,适配器模式可以帮助解决这些问题。

三、适配器模式的实现方式

适配器模式有三种主要的实现方式:类适配器,对象适配器和接口适配器

本文讲解的是类适配器

类适配器

特点

  • 使用继承:类适配器通过继承源类来实现适配功能。

  • 单一适配:由于 Java 中不支持多重继承,类适配器只能适配一个源类。

优缺点

优点
  1. 简单实现
    • 由于类适配器通过继承实现,它可以直接访问被适配类(Adaptee)的所有方法。这使得实现适配器时相对简单,不需要额外的委托逻辑。
  2. 提高代码的可复用性
    • 适配器模式通过继承实现,使得子类能够继承父类的所有功能,从而提高了代码的复用性。
  3. 可以重定义被适配类的一些行为
    • 通过继承,可以在适配器类中重定义被适配类的一些方法,实现更加灵活的适配。
缺点
  1. 受限于单继承
    • 类适配器模式在Java等单继承语言中有一个显著的缺点,即一个类只能继承一个父类。这意味着如果适配器类已经有一个父类,就不能再使用类适配器模式来继承另一个类。
  2. 高耦合
    • 适配器类和被适配类之间的耦合度较高,因为适配器类直接继承了被适配类的实现。如果被适配类发生变化,适配器类可能也需要进行相应的修改。
  3. 不符合“组合优于继承”原则
    • 面向对象设计中,组合优于继承的原则提倡使用组合来代替继承,以降低类之间的耦合度。类适配器模式违背了这一原则,因为它是通过继承来实现适配的。

【例】读卡器

现有一台电脑只能读取SD卡,而要读取TE卡中的内容的话就需要使用到适配器模式。创建一个读卡器,将IE卡中的内容读取出来。

类图如下:

image-20240802094443945

其中:

image-20240802095123937

为适配者类

定义了一个接口 TFCard 接口,有两个方法(读取数据,写数据)。子实现类TFCardImpl重写了接口的两个方法

image-20240802095845883

这一部分为目标接口,主要是SDCard(包含两个方法:读数据,写数据),子实现类为SDcardImpl

image-20240802101005533

Computer只能使用SD卡,所以方法名为readSD(),需要SDcard类型的对象,返回字符串

当我们想用Computer去读取TF卡中的内容,不能直接读取,需要定义适配器类:

image-20240802101330445

我们要让这个适配器类实现目标接口,就要重写SDCard中的两个方法,同时我们要让它去继承TFCardImpl

实现之后这两个方法看似是从SD卡中读数据写数据,但是实际上用的是TF卡中的功能

代码实现

//客户端
public class Client {
    public static void main(String[] args) {
        //创建计算机对象
        Computer computer = new Computer();
        //读取SD卡中的数据
        String msg = computer.readSD(new SDCardImpl());
        System.out.println(msg);

        System.out.println("==============================");

        //使用该电脑读取TF卡中的数据
        //定义适配器类
        String msg1 = computer.readSD(new SDAdapterTF());
        System.out.println(msg1);
    }
}
//计算机类
public class Computer {

    //从SD卡中读取数据
    public String readSD(SDCard sdCard) {
        if (sdCard == null) {
            throw new NullPointerException("sd card is null");
        }
        return sdCard.readSD();
    }
}
//适配器类
public class SDAdapterTF extends TFCardImpl implements SDCard {

    @Override
    public String readSD() {
        System.out.println("adapter read tf card");
        return readTF();
    }

    @Override
    public void writeSD(String msg) {
        System.out.println("adapter wrete tf card");
        writeTF(msg);
    }
}
public interface SDCard {

    //从SD卡中读取数据
    String readSD();
    //往SD卡中写数据
    void writeSD(String msg);
}
//具体的SD卡
public class SDCardImpl implements SDCard{
    @Override
    public String readSD() {
        String msg = "SDCard read msg : SD";
        return msg;
    }

    @Override
    public void writeSD(String msg) {
        System.out.println("SDCard write msg : " + msg);
    }
}
//适配者类的接口
public interface TFCard {

    //从TF卡中读取数据
    String readTF();

    //往TF卡中写数据
    void writeTF(String msg);

}
//适配者类
public class TFCardImpl implements TFCard{

    @Override
    public String readTF() {
        String msg = "TFCard read msg : TF";
        return msg;
    }

    @Override
    public void writeTF(String msg) {
        System.out.println("TFCard write msg : " + msg);
    }
}

四、总结

适配器模式是一种强大的设计模式,能够有效解决接口不兼容的问题,使得不同接口的类能够协同工作。通过合理使用适配器模式,可以提高系统的灵活性和复用性,但也需要注意其可能带来的复杂性和性能影响。

希望本文对你理解适配器模式有所帮助。如果你有任何问题或建议,欢迎在评论区留言!


参考资料:12.设计模式-结构型模式-类适配器模式案例实现_哔哩哔哩_bilibili

已经到底啦!!

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

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

相关文章

2006-2022年中国农村经营管理年报

2006-2022年中国农村经营管理年报 1、时间:2006-2022年 2、格式:2006-2014年为EXCEL,2015-2022年为PDF 3、说明:根据农村经营管理情况统计报表制度调查数据整理、编辑的。本资料系统收录了全国各省、自治区、直辖市农村集体经济…

Gartner发布2024年安全运营成熟度曲线:改变安全运营策略、能力和效果的23项技术发展趋势

安全运营技术和服务通过识别威胁、漏洞和暴露来保护 IT/OT 系统、云工作负载、应用程序和其他数字资产免受攻击。此技术成熟度曲线可帮助安全和风险管理领导者制定战略并提供安全运营能力和功能。 需要知道的 混合和远程工作实践不断发展,安全运营中心 (SOC) 团队支…

云计算 Logstash 配置管理

日志分析系统ELK 项目架构图 Logstash 是一个开源的、服务器端的数据收集引擎,与 Elasticsearch 和 Kibana 一起构成了 Elastic Stack(之前称为 ELK Stack)。Logstash 的主要功能是处理和转发数据,它可以从多种数据源收集数据&a…

Mamba+Transformer完美融合,效果炸裂!

因模型规模的扩展和需要处理的序列不断变长,transformer逐渐出现计算量激增、计算效率下降等问题,研究者们提出了Mamba—— 一种创新的线性时间序列建模方法,它结合了递归神经网络(RNN)和卷积神经网络(CNN)…

十七、Intellij IDEA2022.1.1下载、安装、激活

目录 🌻🌻 一、下载二、 安装三、激活 一、下载 官网下载地址 本地直接下载 目前Intellij IDEA的最新版本已经更新到了 2024.1.4,由于最新版本可能存在不稳定的问题,此处选择其他版本进行下载,此处以2022.1.1为例进行下…

Encoder-Decoder Model编码器-解码器模型

Encoder-Decoder编码器-解码器是一种深度学习模型,应用于图像处理、语音识别、自然语言处理等领域。主要由编码器和解码器两部分组成,这种结构能够处理序列到序列的任务。 编码器-解码器模型具备独特的双阶段处理,先对输入信息进行编码&#…

【C++】实验十五

题目: 1、求一元二次方程ax2bxc0的实根。如果方程没有实根,则利用异常处理处理机制输出有关警告信息 2、学校的人事部门保留了有关学生的部分数据(学号、姓名、年龄、住址)。教务部门也保留了学生的另一些数据(学号、…

最新TomatoIDC开源虚拟主机销售系统源码/有插件系统模块+模版系统

源码简介: 最新TomatoIDC开源虚拟主机销售系统源码,它有一个方便扩展的插件和模版系统模块,使用实用。 TomatoIDC,一款遵循GPL3.0协议的开源虚拟主机销售系统,不仅有着可以轻松扩展的插件系统和模版系统,…

神奇的进度条!水缸进度动画效果怎么实现的?

最近看到一个非常有趣的动画效果:水波进度动画,想了一下实现思路,分享给大家~ 效果如下 图片 图片 基本组件代码 先把最基础的组件代码样式写出来,其实无非就是四个部分: 1、圆形水缸 2、水波 2、百分比数字 3、…

NRK3301识别语音芯片在智能按摩椅中的应用与体验提升

在健康与舒适日益受到关注的今天,按摩椅作为缓解疲劳、舒缓压力的设备受到了广大消费者的喜爱。然而,传统的按摩椅操作方式往往繁琐且不直观。在这一背景下,NRK3301语音识别芯片的应用为按摩椅带来了新的变革。‌ 一、高识别准确率和快速响应…

智能巡检机器人怎么选?

随着科技的快速发展,巡检机器人在工业、能源、交通和安防等领域的应用越来越广泛。选择合适的巡检机器人不仅能显著提高巡检效率和质量,还能有效减少人力成本和安全风险。那么,如何根据具体需求选择适合的巡检机器人呢? 一、明确应…

PC用串口连接开发板进行通讯的底层原理

标题 PC用串口连接开发板进行通讯的底层原理pc端的命令窗口为什么可以看到字符?为什么按下回车后,就有目录信息的显示? PC用串口连接开发板进行通讯的底层原理 小编我开始往驱动开发方向转了,最近在学b站韦东山老师的驱动开发入门…

NET 定时器 Timer和线程Thread

是否可以更新UI线程的内容 》》》资源占用:‌ 》定时器可以的,不存在跨线程问题 》Thread创建的线程,不能更新UI线程的内容, 存在跨线程 Control.CheckForIllegalCrossThreadCalls false;//默认是True 》》执行方式&#xff…

超有用的数据恢复方法!你一定不要错过!

无论我们当下所使用的是何种设备,例如电脑、U 盘、硬盘、相机、行车记录仪,都难以避免出现误删文件的情况。那么,这些被误删的数据究竟应当通过何种方式找回? 今日,为大家分享若干极为实用的数据恢复方法,望…

THS6011容器版docker使用说明(by why+lqw)

THS6011容器版有分x86和arrch64两种安装包,主要是针对ths节点,本身并没有控制台的安装包,请根据自己的系统的cpu架构进行选择,本次使用的是x86的安装包作为演示。 下图是arrch64的镜像(PDMP-4980)&#xf…

大模型书籍分享(附PDF)大模型时代:ChatGPT开启通用人工智能浪潮

近期工作中有一些涉及到大模型等的应用,刚好在微信读书上看到了这本 《大模型时代:ChatGPT开启通用人工智能浪潮》, 本月看完了这本书与大家分享下。 ChatGPT火爆全球,但大语言模型(Large Language Model)…

DeepViT 论文与代码解析

paper:DeepViT: Towards Deeper Vision Transformer official implementation:https://github.com/zhoudaquan/dvit_repo 出发点 尽管浅层ViTs在视觉任务中表现优异,但随着网络深度增加,性能提升变得困难。研究发现&#xff0c…

共享打印机0x0000011b错误解决方法

日打印机故障一直是一个热门话题,特别是共享打印机0x0000011b错误特别头疼,有很多网友经常遇到共享打印机0x0000011b错误。0x0000011b有更新补丁导致的、有访问共享打印机服务异常、有访问共享打印机驱动异常等问题导致的,针对共享打印机0x00…

问题易如反掌?5个常用的AI人工智能助手推荐

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 如今的人工智能技术正以惊人的速度改变着我们的生活方式和工作方式。作为这一变革的关键驱动力,人工智能不仅在科技…

一个方法解决看世界时区 做外贸和跨境电商的必备小工具

一个方法解决看世界时区 做外贸和跨境电商的必备小工具。做过外贸或跨境电商的伙伴们都知道,看世界各地时区是一个比较繁琐的事情。 很多公司都有自己专注的几个地区业务,经常要看业务地区的时间,这样方便和客户沟通。做生意的人都知道&…