java设计模式学习之【适配器模式】

文章目录

  • 引言
  • 适配器模式简介
    • 定义与用途:
    • 实现方式:
      • 类型
  • 使用场景
  • 优势与劣势
  • 适配器模式在Spring中的应用
  • 多媒体播放器示例
  • 代码地址

引言

在我们的日常生活中,适配器无处不在:无论是将不同国家的插头转换成本地标准,还是连接新型耳机和传统音频端口,适配器在我们生活中扮演着重要角色。同样,在软件开发领域,适配器模式也扮演着类似的角色,帮助不兼容的接口实现协同工作。想象一下,如果你有两个组件,它们功能强大,但因为接口不匹配而无法一起工作,该怎么办?适配器模式在这里就像是一个多功能转换插头,连接这些组件,让它们可以协同工作。

适配器模式简介

适配器模式是一种结构型设计模式,它允许你将一个类的接口转换成客户端期望的另一种接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以协同工作。

定义与用途:

  1. 适配器模式主要用于解决两个已有接口之间不匹配的问题,无需修改现有的代码。
  2. 它常用于系统升级或整合过程中,特别是在需要整合第三方库或遗留系统时。

实现方式:

通过将类的实例化过程从客户端代码转移到工厂类,从而减少客户端的复杂性。
适配器模式通常通过创建一个包装类,这个包装类持有一个对已有类的引用,并实现了目标接口。

类型

适配器模式主要有两种类型:

  • 类适配器(Class Adapter):通过继承来实现适配。
  • 对象适配器(Object Adapter):通过组合来实现适配。

使用场景

适配器模式在以下情况下非常有用:

  • 当你想使用一些现有的类,但其接口不符合你的需求。
  • 当你想创建一个可重用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • 当你需要使用几个现有的子类,但是不可能对每一个都进行子类化以匹配它们的接口。适配器可以调整其父接口。

优势与劣势

  • 优势
  • 增加了类的透明性:隐藏了具体实现,客户端代码可以通过统一的接口与不同的实现进行交互。
  • 提高了类的复用性:原本由于接口不兼容无法一起工作的类可以在适配器的帮助下协同工作。
  • 灵活性和扩展性:可以在不修改原有代码的情况下引入新的适配器,使得系统更加灵活。
  • 劣势
  • 过多的使用会使系统变得杂乱:每个适配器都会增加系统的复杂性。
  • 可能会导致代码理解和维护的困难:特别是当有很多适配器参与时,理解它们之间的关系可能会很困难。
  • 增加系统的代码量:为了适配不同的接口,可能需要编写额外的适配器代码。

适配器模式在Spring中的应用

Spring框架中广泛应用了适配器模式,尤其在Spring MVC框架中。Spring用适配器模式来兼容不同类型的控制器实现。

HandlerAdapter:在Spring MVC中,HandlerAdapter 负责将多种类型的请求
处理器(如Controller接口、HttpRequestHandler和SimpleControllerHandlerAdapter)
适配为一个统一的处理流程。视图适配器:Spring MVC使用视图适配器将不同的视图技术(如JSP、
Freemarker、
Thymeleaf)整合到同一模型中,使得控制器可以透明地使用它们。数据访问适配器:Spring通过数据访问适配器简化了对不同数据源的访问,
如JDBC、Hibernate、JPA等,使得业务逻辑可以从具体的数据访问技术中解耦。

多媒体播放器示例

在这个示例中,我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的具体类 AudioPlayer。AudioPlayer 默认可以播放 mp3 格式的音频文件。

我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的具体类。这些类可以播放 vlc 和 mp4 格式的文件。

我们希望 AudioPlayer 也能播放其他格式的音频。为了实现这一点,我们创建了一个适配器类 MediaAdapter,它实现了 MediaPlayer 接口,并使用 AdvancedMediaPlayer 对象来播放所需的格式。

AudioPlayer 使用适配器类 MediaAdapter 并传递它所需的音频类型,而不需要知道实际上哪个类可以播放所需的格式。AdapterPatternDemo(我们的演示类)将使用 AudioPlayer 类来播放各种格式的音频。

在这里插入图片描述
步骤 1:
创建媒体播放器和高级媒体播放器的接口。

public interface MediaPlayer {public void play(String audioType, String fileName);}
public interface AdvancedMediaPlayer {public void playVlc(String fileName);public void playMp4(String fileName);
}

步骤 2:
创建实现 AdvancedMediaPlayer 接口的具体类。

public class VlcPlayer implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {System.out.println("播放 VLC 文件。名称: " + fileName);}@Overridepublic void playMp4(String fileName) {// 无操作}}
public class Mp4Player implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {// 无操作}@Overridepublic void playMp4(String fileName) {System.out.println("播放 MP4 文件。名称: " + fileName);}}

步骤 3:
创建实现 MediaPlayer 接口的适配器类。

public class MediaAdapter implements MediaPlayer{AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType){if(audioType.equalsIgnoreCase("vlc") ){advancedMusicPlayer = new VlcPlayer();} else if (audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer = new Mp4Player();}}@Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer.playVlc(fileName);} else if(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer.playMp4(fileName);}}
}

步骤 4:
创建实现 MediaPlayer 接口的具体类。

public class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {// 内置支持播放 mp3 音乐文件if(audioType.equalsIgnoreCase("mp3")){System.out.println("播放 mp3 文件。名称: " + fileName);}// mediaAdapter 提供支持播放其他文件格式else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);}else {System.out.println("无效媒体。" + audioType + " 格式不支持");}}}

步骤 5:
使用 AudioPlayer 来播放不同类型的音频格式。

public class AdapterPatternDemo {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "beyond the horizon.mp3");audioPlayer.play("mp4", "alone.mp4");audioPlayer.play("vlc", "far far away.vlc");audioPlayer.play("avi", "mind me.avi");}
}

在这里插入图片描述

代码地址

23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern

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

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

相关文章

数学建模回归分析part2

回归系数的解释 思考: y b b1*Inx;此时b1怎么解释? 什么时候取对数 经验法则: (1)与市场价值相关的,例如,价格、销售额、工资等都可以取对数;(2)以年度量的变量,如受…

相控阵天线(十五):进阶稀疏阵列天线(边缘稀疏阵列、稀疏子阵天线、旋转稀疏子阵天线)

目录 简介圆形边缘稀疏阵列矩形边缘稀疏阵列稀疏子阵天线旋转稀疏子阵天线 简介 前面的博客已经介绍过常见的平面阵有一些基本类型,本篇博客介绍一些实际工程中可能出现的阵列,包括椭圆阵列、子阵通过矩形拼接形成的矩形大阵列和圆形大阵列、子阵通过三…

开源项目CuteSqlite开发笔记(二):SQLite的架构

在开发CuteSqlite图形客户端的时候,需要用到SQL的语法解释,来对SQL语句进行优化。找了很多的SQL语法解释器,都不是十分满意,只有翻开Sqlite的源码,看看SQLite对SQL语句的解释过程,本文是翻译的官方文档。 官…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑气电联合需求响应的气电综合能源配网系统协调优化运行》

这个标题涉及到一个涉及气体(天然气)和电力的综合能源配网系统,并且强调了考虑气电联合需求响应的协调优化运行。让我们逐步解读: 气电综合能源配网系统: 这指的是一个结合了气体(通常是天然气)…

柔性数组详解

目录 一、柔性数组的特点:​ 二、使用sizeof计算包含柔性数组的结构体的大小 三、柔性数组的使用 代码1: 四、用结构体指针代替柔性数组 代码2: 五、柔性数组与结构体指针对比 • 在结构体中 • 最后一个成员 • 未知大小的数组 这就是柔性…

吴恩达《机器学习》12-1:优化目标

在机器学习的旅程中,我们已经接触了多种学习算法。在监督学习中,选择使用算法 A 还是算法 B 的重要性逐渐减弱,而更关键的是如何在应用这些算法时优化目标。这包括设计特征、选择正则化参数等因素,这些在不同水平的实践者之间可能…

代码随想录算法训练营第三十八天|完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ

完全背包 例题:有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。 区别&#x…

机器学习硬件十年:性能变迁与趋势

本文分析了机器学习硬件性能的最新趋势,重点关注不同GPU和加速器的计算性能、内存、互连带宽、性价比和能效等指标。这篇分析旨在提供关于ML硬件能力及其瓶颈的全面视图。本文作者来自调研机构Epoch,致力于研究AI发展轨迹与治理的关键问题和趋势。 &…

小红书蒲公英平台开通后,有哪些注意的地方,以及如何进行报价?

今天来给大家聊聊当小红书账号过1000粉后,开通蒲公英需要注意的事项。 蒲公英平台是小红书APP中的一个专为内容创作者设计的平台。它为品牌和创作者提供了一个完整的服务流程,包括内容的创作、推广、互动以及转换等多个方面。 2.蒲公英平台的主要功能 &…

第一启富金:新添澳大利亚(ASIC)牌照

第一启富金:澳大利亞證券及投資委員會(ASIC) GOLDWELL GLOBAL PTY LTD 是 WHOLESALE INVESTOR SERVICES PTY LTD(CAR 編號 001304943)的企業授權代表開發澳大利亞客戶,WHOLESALE INVESTOR SERVICES PTY LT…

前端学习系列之CSS

目录 CSS 简介 发展史 优势 基本语法 引用方式 内部样式 行内样式 外部样式 选择器 id选择器 class选择器 标签选择器 子代选择器 后代选择器 相邻兄弟选择器 后续兄弟选择器 交集选择器 并集选择器 通配符选择器 伪类选择器 属性选择器 CSS基本属性 优…

Java_LinkedList链表详解

目录 前言 ArrayList的缺陷 链表 链表的概念及结构 链表的种类 1.单向或双向 2.带头或不带头 3.循环或不循环 LinkedList的使用 什么是LinkedList LinkedList的使用 LinkedList的构造 LinkedList的其他常用方法介绍 LinkedList的遍历 ArrayList和LinkedList的…