Java设计模式 _结构型模式_适配器模式

一、适配器模式

**1、适配器模式(Adapter Pattern)**是一种结构型设计模式。适配器类用来作为两个不兼容的接口之间的桥梁,使得原本不兼容而不能一起工作的那些类可以一起工作。譬如:读卡器就是内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取或写入数据到内存卡。

2、实现思路
总的来说:实现业务类注入适配器中,适配器注入调用类中。调用类使用适配器的方法,适配器使用实现业务类的方法。
具体步骤如下:
(1)、创建适配器类(Adapter),实现和业务类(Computer)相同的功能接口(Abilities)
(2)、适配器类注入功能接口(Abilities)的属性类。重写构造方法,根据传入或其他参数实例化这个属性类
(3)、适配器类实现功能接口(Abilities)的抽象方法,通过自身的属性类去实现调用。
(4)、在业务类(Computer)中,注入适配器类(Adapter)的属性类,重写构造方法实例化适配器。
(5)、在业务类中,使用适配器的实现方法替换原本自身的实现方法。

二、代码示例

1、示例1
电脑(Computer),内存卡(MemoryCard),读卡器(ReadCardAdapter)。电脑通过读卡器完成对内存卡数据的读取和写入。
代码示例:

// 定义规范超类,读取数据,写入数据的接口
public interface Abilities {// 读取数据public void readData();// 存储数据public void storeData();
}
// 定义内存卡类
public class MemoryCard implements Abilities{@Overridepublic void readData() {System.out.println("读取了内存卡数据");}@Overridepublic void storeData() {System.out.println("数据存储到内存卡");}
}
// 定义适配器类,需要实例具体的业务类
public class CardReaderAdapter implements Abilities {private MemoryCard memoryCard;public CardReaderAdapter(MemoryCard memoryCard){this.memoryCard = memoryCard;}@Overridepublic void readData() {memoryCard.readData();}@Overridepublic void storeData() {memoryCard.storeData();}
}
// 定义电脑类,注入适配器类
public class Computer implements Abilities{private CardReaderAdapter cardReaderAdapter;public Computer(CardReaderAdapter cardReaderAdapter){this.cardReaderAdapter =cardReaderAdapter;}@Overridepublic void readData() {cardReaderAdapter.readData();}@Overridepublic void storeData() {cardReaderAdapter.storeData();}
}
// 测试
public class Ztest {public static void main(String[] args) {MemoryCard memoryCard = new MemoryCard();CardReaderAdapter adapter = new CardReaderAdapter(memoryCard);Computer computer = new Computer(adapter);computer.readData();computer.storeData();}
}

运行结果:
在这里插入图片描述
上图可以看出,虽然实现的是电脑的实例对象,调用的确实内存卡的业务实现方法。说明适配器生效了。

2、示例2
原本的音频播放器(AudioPlayer),仅支持播放mp3,现在需要扩展播放wav格式和pcm格式的文件
最初代码示例:

// 定义规范超类,播放文件的接口
public interface Abilities {void play(String name);
}
// 定义音频播放器类,播放mp3文件
public class AudioPlayer implements Abilities {@Overridepublic void play( String name) {String type = name.substring(name.indexOf(".")+1);if ("mp3".equals(type)) {System.out.println("原生播放器播放:" + name);} else {System.out.println("不支持的格式!");}}
}
// 测试
public class Ztest {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("青花瓷.mp3");audioPlayer.play("鸟语花香.wav");}
}

运行结果
在这里插入图片描述
可以看到目前仅支持播放mp3的文件,其他格式不支持播放。

改造思路:
编写扩展的实例类,通过注入适配器,将适配器注入原始类的方法,实现原始类可以调用自身方法或者适配器方法的多种情形。
在这里插入图片描述

使用适配器修改后,代码示例如下:

// 定义规范超类,播放文件的接口
public interface Abilities {void play(String name);
}
// 创建播放wav格式的实例类,实现超类
public class WavPlayer implements Abilities {@Overridepublic void play(String name) {System.out.println("Wav播放器播放:" + name);}
}
// 创建播放pcm格式的实例类,实现超类
public class PcmPlayer implements Abilities {@Overridepublic void play(String name) {System.out.println("Pcm播放器播放:" + name);}}
// 创建适配器类,根据业务场景注入超类的实例,调用注入实例的实现方法
public class AudioAdapter implements Abilities {private Abilities abilitiesPlay;public AudioAdapter(String type) {if ("wav".equals(type)) {this.abilitiesPlay = new WavPlayer();} else if ("pcm".equals(type)) {this.abilitiesPlay = new PcmPlayer();}}@Overridepublic void play(String name) {abilitiesPlay.play(name);}
}
// 修改音频播放器,注入适配器,根据条件选择调用原生方法或者适配器的方法
public class AudioPlayer implements Abilities {private AudioAdapter audioAdapter;@Overridepublic void play(String name) {String type = name.substring(name.indexOf(".") + 1);if ("mp3".equals(type)) {System.out.println("原生播放器播放:" + name);} else if ("wav".equals(type) || "pcm".equals(type)) {audioAdapter = new AudioAdapter(type);audioAdapter.play(name);} else {System.out.println("不支持的格式!");}}
}
// 测试
public class Ztest {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("青花瓷.mp3");audioPlayer.play("青鸟.wav");audioPlayer.play("鼓风机采集声音.pcm");audioPlayer.play("鸟语花香.avi");}
}

运行结果:
在这里插入图片描述
上图可以看到已经支持播放了两种新的格式的文件。

学海无涯苦作舟!!!

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

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

相关文章

C语言笔试题之找出数组的最大公约数

找出数组的最大公约数 实例要求 1、给定一个整数数组 ,返回数组中最大数和最小数的最大公约数;2、两个数的最大公约数是能够被两个数整除的最大正整数;示例: 实例分析 1、要找到数组中最大数和最小数的最大公约数&#xff1b…

【后端】python与django的开发环境搭建指南

安装Git 双击Git 客户端安装文件,在安装页面,单击“Next” 在安装路径选择页面,保持默认,单击“Next” 在功能组件选择页面,保持默认,单击“Next” 在开始菜单文件夹设置页面,保持默认&am…

阿斯达年代记游戏下载教程 阿斯达年代记下载教程

《阿斯达年代记:三强争霸》作为一款气势恢宏的MMORPG大作,是Netmarble与STUDIO DRAGON强强联合的巅峰创作,定于4月24日迎来全球玩家热切期待的公测。游戏剧情围绕阿斯达大陆的王权争夺战展开,三大派系——阿斯达联邦、亚高联盟及边…

无人机反制:高功率微波反无人机系统技术详解

随着无人机技术的快速发展,无人机在民用和军用领域的应用越来越广泛。然而,无人机滥用、非法入侵和恶意攻击等问题也日益凸显,对国家安全、公共安全和个人隐私造成了严重威胁。因此,研发高效、快速、安全的无人机防御系统成为当前…

【如此简单!数据库入门系列】之ER模型快速入门

文章目录 模式设计基本概念实体(Entity)属性(Attributes)实体集和键(key)关系(Relationship) ER图实体和属性关系 泛化与特化总结更多例子 模式设计 大家还记得什么是物理模式、概念…

Git--基础学习--面向企业--持续更新

一、基础学习 1.1基本命令 //查询基础信息 git config --global --list //选取合适位置创建 mkdir 文件名 //创建文件夹 //全局配置 git config --global user.email "****e***i" git config --global user.name "*** K****"//--------------------进入…

网传Llama 3比肩GPT-4?别闹了

相信大家近期都被Llama 3刷屏了。Llama 3的预训练数据达到了15万亿,是Llama 2的7倍;微调数据用了100万条人工标注数据,是Llama 2的10倍。 足以看出Meta训练Llama 3 是下了大血本的。开源社区拥抱Llama3也是空前热烈,发布才4天Hug…

Kafka 消费者应用解析

目录 1、Kafka 消费方式 2、Kafka 消费者工作流程 2.1、消费者工作流程 2.2、消费组者说明 1、消费者组 2、消费者组初始化流程 3、消费者 API 3.1、独立消费者-订阅主题 3.2、独立消费者-订阅分区 3.3、消费组 4、分区的分配策略以及再平衡 4.1、Range 策略 1、R…

win11 修改hosts提示无权限

win11下hosts的文件路径 C:\Windows\System32\drivers\etc>hosts修改文件后提示无权限。 我做了好几个尝试,都没个啥用~比如:右键 管理员身份运行,在其他版本的windows上可行,但是win11不行,我用的是微软账号登录的…

为什么单片机控制电机需要加电机驱动

通常很多地方只是单纯的单片机MCU没有对电机的驱动能力,或者是介绍关于电机驱动的作用,如: 提高电机的效率和精度。驱动器采用先进的电子技术和控制算法,能够精准控制电机的参数和运行状态,提高了电机的效率和精度。拓…

《第二行代码》第二版学习笔记(6)——内容提供器

文章目录 一 运行时权限2.权限分类3 运行时申请权限 二、内容提供器1、 ContentResolver的基本用法2、现有的内容提供器3、创建自己的内容提供器2.1 创建内容提供器的步骤2.2 跨程序数据共享 内容提供器(Content Provider)主要用于在不同的应用程序之间实…

普通人与AIGC的日常

AIGC时代之前 当ChatGPT3还没有推出来之前,可以肯定的是绝大多数的人没有接触过生成式AI,也不知道什么是生成式AI,更别说生成式AI能为我们做些什么了。 以前上网找资料,一般都是通过搜索引擎,比如国内的百度&#xf…