适配器模式:代码接口的神奇转换

news2025/1/10 15:39:27

一、概要

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作。通俗来讲,就是通过适配器来连接两个不兼容的接口,让客户端通过调用一个通用的接口,而间接实现对其他功能接口的调用。打个形象的比喻,适配器就好比我们生活中的三充数据线,可以适配不同的充电接口。

如何实现?

举个实际案例,我有一个播放器接口Player以及它的实现类MediaPlayer,当前它的功能有限,只允许播放MP3音频文件。另有一个VideoPlayer接口和其实现Mp4Player,是用于播放MP4视频文件的,但是该接口不开放给客户端直接调用。如果现在我要让Player可以支持MP4视频播放,要如何实现呢?

adaptermodeusecasenew

为了解决这个问题,我们就可以引入适配者模式,客户端仍然调用Player接口,然后通过适配者将调用转发到VideoPlayer接口上,以达到播放MP4的目的。

adaptermode

优点

  • 解决接口不兼容问题:适配器模式能够解决不同类之间接口不兼容的问题。通过适配器,客户端可以使用期望的接口,而不需要修改现有的代码或对象。
  • 复用现有的类:适配器模式可以复用已有的类,而无需修改其代码。通过适配器,可以将现有的类包装起来,以适应新的接口。
  • 增加类的透明性:适配器模式使得客户端无需关注被适配的类的具体实现细节,只需要通过适配器与其交互。
  • 灵活性和扩展性:适配器模式可以在不影响现有代码的情况下添加新的适配器类,从而实现对新接口的适配,提高系统的灵活性和扩展性。

缺点

  • 增加了系统的结构复杂性:因为需要引入新的类和对象,过多的适配器可能导致代码混乱和难以维护。
  • 可能引入性能损耗:适配器模式可能会引入额外的性能损耗,因为在转换接口时需要进行额外的处理和转换操作。在性能敏感的系统中需要谨慎使用适配器模式。

适用场景

  • 当需要使用一个已经存在的类或接口,但其接口与现有系统的接口不兼容时,可以使用适配器模式来适配新旧接口,使其能够协同工作。
  • 当系统中存在多个类或组件,其接口不一致,但需要对外提供统一的接口时,可以使用适配器模式将不同接口转换为统一的接口,以便客户端使用。
  • 当需要集成第三方库或组件到自己的系统中,但其接口与自己的系统不匹配时,可以使用适配器模式来将第三方库的接口转换为自己系统所期望的接口。

二、代码实现

步骤1:VideoPlayer接口和Mp4Player实现

public interface VideoPlayer {
    void playVideo(String filename);
}
public class Mp4Player implements VideoPlayer {
    @Override
    public void playVideo(String filename) {
        System.out.println("播放MP4视频:"+filename);
    }
}

步骤2:通用接口Player

public interface Player {
    void play(String filename);
	
    //接口中的默认方法,用于返回文件格式
    default String getFileType(String filename){
        if(filename.endsWith(".mp3")){
            return "mp3";
        }else if(filename.endsWith(".mp4")){
            return "mp4";
        }else{
            return "unknown";
        }
    }
}

步骤3:添加适配器MediaAdapter

public class MediaAdapter implements Player {
    VideoPlayer videoPlayer;

    public MediaAdapter(){
        videoPlayer=new Mp4Player();
    }

    @Override
    public void play(String filename) {
        videoPlayer.playVideo(filename);
    }
}

步骤4:媒体播放器MediaPlayer----使用适配器兼容MP4格式

public class MediaPlayer implements Player {

    MediaAdapter mediaAdapter;

    @Override
    public void play(String filename) {
        if("mp3".equals(getFileType(filename))){
            System.out.println("播放MP3音频:"+filename);
        }else if("mp4".equals(getFileType(filename))){
            mediaAdapter =new MediaAdapter();
            mediaAdapter.play(filename);
        }else{
            System.out.println("Invalid media :format not supported");
        }
    }
}

步骤5:客户端测试

public  class Client {
    public static void main(String[] args) {
        Player play=new MediaPlayer();
        play.play("aaa.mp3");
        play.play("bbb.mp4");
        play.play("ccc.avi");
    }
}

测试结果

image-20230524080416656

三、总结

本文详细介绍了适配器模式,并通过一个简单的案例,让你轻松掌握适配器模式的原理和应用。适配器模式可以解决接口不兼容、系统扩展、集成多个接口等问题,并提高代码的复用性和灵活性。然而,它也可能增加系统的复杂性,并引入性能损耗。在使用适配器模式时,需要根据具体情况权衡利弊,并避免过度使用适配器导致代码混乱。

希望这篇文章对你的学习有所帮助!如果你觉得这篇文章对你有帮助,请不要吝啬你的赞美和分享。在此感谢你的阅读,我们下次再见!
1711edbd2bd444b1b647e09c2c3aff0d

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

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

相关文章

Js 如何实现一个类似 chatGPT 打字机效果

在使用chatGPT的时候,会有一个打字机的效果,以下是分别使用原生Js和Vue实现 原生 JS 实现 如下是示例代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Printer 打字机效果</title><style>* {margin: 0;bor…

记录--使用率比较低的10个Web API

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 avaScript中有些API可能使用率比较低&#xff0c;下面我们逐一介绍它们的用法和使用场景。 至于标题&#xff0c;主要是想让你进来看看&#xff0c;兄弟们别打我&#xff01; Blob API Blob API 用于处…

电脑技巧:CopyQ剪切板增强工具介绍(附下载)

目录 1、软件简介 2、主要功能介绍 3、使用说明 4、总结 今天给大家再分享一款剪切板增强工具——CopyQ&#xff0c;感兴趣的朋友可以下载试一试&#xff01; 1、软件简介 CopyQ 是一款开源的、跨平台剪贴板管理工具&#xff0c;支持 Windows、macOS、Linux&#xff0c;可…

项目中遇到的一些问题总结(十)

nacos保护阈值 Nacos 中的保护阈值&#xff08;Protection Threshold&#xff09;是用来保护服务实例的一种机制。当某个服务实例出现故障或异常时&#xff0c;服务注册中心 Nacos 会通过心跳检测等方式将其从服务列表中移除&#xff0c;以避免客户端继续向其发送请求。但是&a…

在Linux中为Simulink添加ROS自定义消息类型

在Linux中为Simulink添加ROS自定义消息类型 基于Matlab/Simulink的ROS自定义消息类型的添加方法 ROS与Simulink联合仿真(三):自定义Message 1、下载 ROS Toolbox Interface for ROS Custom Messages 将 roscustommsg.mlpkginstall 文件放入 MATLAB 工作空间 双击 roscustommsg…

Nature -- 人类首个 “泛基因组”旨在编目人类遗传多样性

在人类基因组项目发布第一个人类基因组草图的20多年后,研究人员发布了人类“泛基因组”草图——这预示着一种新的参考基因组的出现,它能捕获到更多的人类遗传多样性信息。 泛基因组变异图由两个元素组成:序列图&#xff0c;其ode表示定向DNA链&#xff0c;双向边表示连通性关系…

学系统集成项目管理工程师(中项)系列25_计算机网络知识

1. OSI七层协议 1.1. 物理层 1.1.1. RS232、V.35、RJ-45、FDDI 1.2. 数据链路层 1.2.1. 【21上选17】 1.2.2. IEEE802.3/.2、HDLC、PPP、ATM 1.3. 网络层 1.3.1. IP、ICMP、IGMP、IPX、ARP 1.3.2. 路由选择 1.3.2.1. 【20下选17】 1.4. 传输层 1.4.1. TCP、UDP、SPX…

越小越好: Q8-Chat,在英特尔至强 CPU 上体验高效的生成式 AI

大语言模型 (LLM) 正在席卷整个机器学习世界。得益于其 transformer 架构&#xff0c;LLM 拥有从大量非结构化数据 (如文本、图像、视频或音频) 中学习的不可思议的能力。它们在 多种任务类型 上表现非常出色&#xff0c;无论是文本分类之类的抽取任务 (extractive task) 还是文…

又一批令人惊艳的 AI 工具,诞生了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 自 ChatGPT 发布以后&#xff0c;AIGC 行业的热度也一直在持续发酵。几个月过去了&#xff0c;对比之前&#xff0c;各类 AI 工具的热度不减反增&#xff0c;各行各业的人都早开始拥抱 AIG…

SAP工具箱 MR22自定义BAPI

点击蓝字 关注我们 一 前言 标准事务代码MR22 通过调整金额影响物料的成本价,前台界面中单个凭证中允许输入多行物料, 但是对应的BAPI函数仅支持输入单行物料 BAPI_MATVAL_DEBIT_CREDIT 正常库存BAPI_SALESORDSTCK_DEBIT_CREDIT 销售订单库存 这种情况 婶可忍叔不可忍 (感谢用户…

Python 闭包装饰器和多任务--闭包,装饰器,进程,线程

1.闭包案例 在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包. 外层函数: config_name(),外层函数中的变量是 name 内层函数: inner(),inner()使用了外层函数的变…

34从零开始学Java之构造方法都有哪些特性?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在前面的几篇文章中&#xff0c;壹哥给大家介绍了不少关于方法的内容&#xff0c;这些内容是我们日常…

zabbix监控之javasnmp自定义监控

1、客户端开启 java jmxremote 远程监控功能 上传 tomcat 软件包到 /opt 目录中 cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mv apache-tomcat-9.0.16 /usr/local/tomcat #配置 java jmxremote 远程监控功能 vim /usr/local/tomcat/bin/catalina.sh ...... #位置在 cygw…

嵌入式音视频开发面试过程遇到的问题!

前言&#xff1a; 今天继续给大家分享音视频面试过程会被常问到的一些问题&#xff01; 面试的具体题目&#xff1a; 1、说一下播放器的设计过程&#xff1a; 这里的话主要分以下几步完成&#xff1a; 开启一个线程进行解封装操作 , 这包括&#xff1a;读取音频、视频的压缩数据…

chatgpt赋能Python-python_ps图片

Python PS图片的SEO指南 Python在数字图像处理中广泛应用。其中&#xff0c;Photoshop文件&#xff08;psd&#xff09;是一种常见的图像文件格式。但是&#xff0c;如何在搜索引擎上优化Python PS图片并提高其排名仍然是一个挑战。 什么是Python PS图片&#xff1f; Python…

数据结构和算法基础学习1

​​​​​​​ 网址第01周b--1.1数据结构研究_哔哩哔哩_bilibili

学C的第十九天【实用调试技巧:1. 调试;2. Windows环境调试介绍;3. 一些调试的实例;4. 一些调试的实例】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a;学C的第十八天【指针初阶&#xff1a;5. 指针和数组、6. 二级指针、7. 指针数组&#xff1b;初识结构体&#xff1a;1. 结构体的声明、2. 结构体成员的访问、3. 结构体传参&#xff1b…

java中的栈、堆、方法区

栈&#xff08;stack&#xff09; Java栈与堆不同每一个线程都有一个stack&#xff0c;栈的区域非常小&#xff0c;大概只有1M左右&#xff0c;但是存储速度非常快&#xff0c;所以我们把快速执行的任务存储在stack。 特点&#xff1a;自动分配&#xff0c;连续空间&#xff0…

如何从文档中提取结构化数据?parsio.io

parsio.io 产品名&#xff1a;Parsio电子邮件解析器 技术&#xff1a;采用人工智能技术的电子邮件解析器。 支持多种格式&#xff1a; 可以解析电子邮件和附件中的数据&#xff0c;包括PDF、HTML、XLSX&#xff08;Excel&#xff09;、CSV、DOCX、XML、TXT等格式。 提取模版&am…

FANUC机器人作为EtherCAT通信从站的相关配置方法

FANUC机器人作为EtherCAT通信从站的相关配置方法 基本介绍: 前提条件: 硬件部分: 机器人需要使用EtherCAT从站板卡 A20B-8101-0821。使用带屏蔽层的网线连接板卡和PLC的网口。 本例中使用的网络接口为EC-IN(CD38Y) 软件部分: 机器人需要安装软件:1A05B-2600-J743! Et…