适配器模式 详解 设计模式

适配器模式

适配器模式是一种结构型设计模式,其主要作用是解决两个不兼容接口之间的兼容性问题。适配器模式通过引入一个适配器来将一个类的接口转换成客户端所期望的另一个接口,从而让原本由于接口不匹配而无法协同工作的类能够协同工作。

结构

适配器模式(Adapter)包含以下主要角色:

  • 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  • 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  • 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

图例:

在这里插入图片描述

AudioPlayer实现了 MediaPlayer 接口,只可以播放 mp3 。实现了 AdvancedMediaPlayer 接口的类则可以播放 vlc 和 mp4 格式的文件。可以创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 的实现类对象来播放所需的格式。AdapterPatternDemo 类则可以使用 AudioPlayer 类来播放各种格式的音频。

对象适配器模式代码案例:

// 目标接口
interface MediaPlayer {void play(String audioType, String filename);  
}// 适配器接口
interface AdvancedMediaPlayer {void playVlc(String filename);void playMp4(String filename);
}// 适配器类
class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMediaPlayer;public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase("vlc")) {advancedMediaPlayer = new VlcPlayer();} else if (audioType.equalsIgnoreCase("mp4")) {advancedMediaPlayer = new Mp4Player();}}@Overridepublic void play(String audioType, String filename) {if (audioType.equalsIgnoreCase("vlc")) {advancedMediaPlayer.playVlc(filename);} else if (audioType.equalsIgnoreCase("mp4")) {advancedMediaPlayer.playMp4(filename);}}
}// 具体实现类
class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String filename) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + filename);} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, filename);} else {System.out.println("Invalid media. " + audioType + " format not supported");}}
}class VlcPlayer implements AdvancedMediaPlayer {@Overridepublic void playVlc(String filename) {System.out.println("Playing vlc file. Name: " + filename);}@Overridepublic void playMp4(String filename) {// Do nothing}
}class Mp4Player implements AdvancedMediaPlayer {@Overridepublic void playVlc(String filename) {// Do nothing}@Overridepublic void playMp4(String filename) {System.out.println("Playing mp4 file. Name: " + filename);}
}// 使用示例
public class Main {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "song.mp3");audioPlayer.play("vlc", "movie.vlc");audioPlayer.play("mp4", "video.mp4");}
}

适配器模式有类适配器模式和对象适配器模式;这里使用对象适配器模式主要是类适配器模式违背了合成复用原则,它限制了适配器类只能适配一个具体的被适配者类。且Java 不支持多重继承,因此在 Java 中一般使用接口来实现类似的功能

比如下面类适配器,采用的是继承:

// 适配器类(类适配器)
class MediaAdapter extends Mp4Player implements MediaPlayer { @Overridepublic void play(String audioType, String filename) {if (audioType.equalsIgnoreCase("vlc")) {playVlc(filename);} else if (audioType.equalsIgnoreCase("mp4")) {playMp4(filename);}}
}

当然,也有接口适配器模式,不过使用相对较少。当一个接口拥有许多方法,但实现类只需要实现其中一部分方法时,可以使用接口适配器模式,提供一个抽象适配器类实现该接口,并提供默认实现,从而避免实现类需要实现大量空方法。

使用场景:

  • 当需要使用一个已经存在的类,但是它的接口不符合当前需求时,可以考虑使用适配器模式。
  • 当需要复用一些已经存在的类,但是接口与其他类不兼容时,可以考虑使用适配器模式。
  • 当需要创建一个可复用的类,该类可以与不相关或不可预见的类协同工作时,可以考虑使用适配器模式。

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

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

相关文章

机器学习高手之路:发现TensorFlow学习网站的无限可能!

介绍:TensorFlow是一个由Google团队开发的端到端开源机器学习平台,专为数值计算和机器学习而设计。以下是对TensorFlow的详细介绍: 开发背景与历史:TensorFlow起源于谷歌的神经网络算法库DistBelief。它被设计成一个灵活的深度学习…

CSAPP-信息的表示和处理

文章目录 概念扫盲思想理解经典好图安全事件 概念扫盲 1.大端高位在前,小端低位在前 2.逻辑运算符(&& 、||、!)与位级运算(&、|、~)的差异 3.宏可以保证无论代码如何编译,都能生成…

【Java】UWB高精度工业定位系统项目源代码

目录 UWB技术原理 优势 1. 高精度: 2. 抗干扰能力强: 3. 定位范围广: 4. 实时性强: 应用前景 定位系统源码功能介绍 实时定位: 轨迹回放: 区域管理: 巡检管理: 数据可视化分析&…

解决GitHub无法访问的问题:手动修改hosts文件与使用SwitchHosts工具

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…

Java 封装阿里云 oss 上传图片时抽取配置到 application 使用 @Value 获取值

Java 封装阿里云 oss 上传图片时抽取配置到 application 使用 Value 获取值 application .yml 配置 alioss: # 阿里云配置endpoint: "https://oss-cn-beijing.aliyuncs.com" # Endpoint以华东1(杭州)为例,其它Region请按实际…

centos7安装kafka、zookeeper

安装jdk 安装jdk8 安装zookeeper 在指定目录执行下载命令 我是在/newdisk/zookeeper目录下 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.8/apache-zookeeper-3.5.8-bin.tar.gz --no-check-certificate下载好后并解压 tar -zxvf apache-zookeeper-3.5…

VScode 单步断点调试Nodejs方法总结

目录 方法一 方法二 方法三 方法一 使用vscode开发nodejs程序,能够启动单步调试模式,在指定代码处添加断点,像chrome、firefox浏览器上一样进行JavaScript的调试。 新建一个nodejs的工程,编写代码后,配置代码调试的步骤: 1、切换到代码调试界面 2、界面提示,新建一…

【二分】二分模板+二分题目

一、朴素二分 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/binary-search/description/ int left 0, right nums.…

震惊!python类型的自动化测试框架原来这么简单!

自2018年被评选为编程语言以来,Python在各大排行榜上一直都是名列前茅。目前,它在Tiobe指数中排名第三个,仅次于Java和C。随着该编程语言的广泛使用,基于Python的自动化测试框架也应运而生,且不断发展与丰富。 因此&am…

SpringBoot 的基础使用与入门(总结众多文章与实践)

一:介绍 1、SpringBoot概念 从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用。简便起见,该框架也提供了命令行界面,它可以用来运行和测试Boot应用。框架的发布版本,包括集成…

C#使用iText7将多个PDF文档合并为单个文档

使用HtmlAgilityPack抓取并分析网页内容,然后再调用PuppeteerSharp将网页生成PDF文件,最终的成果如下图所示,得到将近120个pdf文档。能看,但是不方便,需要逐个打开文档才能看到所需的内容,最好能将这些文档…

初学HTMLCSS——盒子模型

盒子模型 盒子:页面中所有的元素(标签),都可以看做是一个 盒子,由盒子将页面中的元素包含在一个矩形区域内,通过盒子的视角更方便的进行页面布局盒子模型组成:内容区域(content&…