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{
    @Override
    public void readData() {
        System.out.println("读取了内存卡数据");
    }
    @Override
    public void storeData() {
        System.out.println("数据存储到内存卡");
    }
}
// 定义适配器类,需要实例具体的业务类
public class CardReaderAdapter implements Abilities {
    private MemoryCard memoryCard;
    public CardReaderAdapter(MemoryCard memoryCard){
        this.memoryCard = memoryCard;
    }
    @Override
    public void readData() {
        memoryCard.readData();
    }
    @Override
    public void storeData() {
        memoryCard.storeData();
    }
}
// 定义电脑类,注入适配器类
public class Computer implements Abilities{
    private CardReaderAdapter cardReaderAdapter;
    public Computer(CardReaderAdapter cardReaderAdapter){
        this.cardReaderAdapter =cardReaderAdapter;
    }
    @Override
    public void readData() {
        cardReaderAdapter.readData();
    }
    @Override
    public 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 {
    @Override
    public 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 {
    @Override
    public void play(String name) {
        System.out.println("Wav播放器播放:" + name);
    }
}
// 创建播放pcm格式的实例类,实现超类
public class PcmPlayer implements Abilities {
    @Override
    public 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();
        }
    }

    @Override
    public void play(String name) {
        abilitiesPlay.play(name);
    }
}
// 修改音频播放器,注入适配器,根据条件选择调用原生方法或者适配器的方法
public class AudioPlayer implements Abilities {
    private AudioAdapter audioAdapter;
    
    @Override
    public 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");
    }
}

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

学海无涯苦作舟!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sy8网络管理命令(ubuntu23.10和centos8)

前言、 本次实验主要是扩展学习,不仅限在课本的内容。毕竟课本的内容太过于陈旧了。需要的童鞋看看。 说明:(书本中sy9”第3.实验内容“大家还是要做下。) 1、使用ubuntu做实验的童鞋只要看第二、三、四、七章节的部分内容。 2、使…

单片机为什么有多组VDD?

以前我在画尺寸小的PCB时,比较头痛,特别是芯片引脚又多的,芯片底下,又不能打太多过孔。 可能有些老铁也比较好奇,为什么一个单片机芯片,有这么多组VDD和VSS。 比如下面这个100个引脚的STM32单片机。 有5组…

Blender基础操作

1.移动物体: 选中一个物体,按G,之后可以任意移动 若再按X,则只沿X轴移动,同理可按Y与Z 2.旋转物体: 选中一个物体,按R,之后可以任意旋转 若再按X,则只绕X轴旋转&…

STM32、GD32等驱动AMG8833热成像传感器源码分享

一、AMG8833介绍 1简介 AMG8833是一种红外热像传感器,也被称为热感传感器。它可以用来检测和测量物体的热辐射,并将其转换为数字图像。AMG8833传感器可以感知的热源范围为-20C到100C,并能提供8x8的像素分辨率。它通过I2C接口与微控制器或单…

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行,但很多开发人员仍然不清楚它是如何实际运作的,这是非常正常的。 平台工程是与 DevOps 并行吗?还是可以相互替代?或者 DevOps 和平台工程是两个完全不同的概念? 一种比较容易将两者区分开来的方…

Feign负载均衡

Feign负载均衡 概念总结 工程构建Feign通过接口的方法调用Rest服务(之前是Ribbon——RestTemplate) 概念 官网解释: http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebService客户端。使用Feign能让…

AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化

系列文章目录🚩 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据…

法律知识学习考试系统 C#+uniapp+asp.net微信小程序

技术要求:后端C#,安卓app,mysql数据库 系统分为管理员、教师端和学生端: 管理员端实现管理员的注册登录以及教师和学生的注册、法律法规内容的发布与更新、法律法规页面的评论的添加与删除、内容查询、知识小测的内容发布与删除、问卷调查的发…

云计算和边缘计算究竟有什么不同

在数据时代,无论是人的活动还是机器的运作都会产生各种各样海量的数据。在对数据梳理和筛选过程中,计算机的运算处理必不可少。为了减少本地计算机算力成本等限制,越来越多的企业选择了云计算和边缘计算。今天,德迅云安全就带您来…

SpikingJelly笔记之梯度替代

文章目录 前言一、梯度替代二、网络结构三、MNIST分类1、单步模式2、多步模式 总结 前言 在SpikingJelly使用梯度替代训练SNN,构建单层全连接SNN实现MNIST分类任务。 一、梯度替代 1、梯度替代: 阶跃函数不可微,无法进行反向传播 g ( x ) …

miniTry:Python实现web搜索(全自动+程序操控)

声明:本问给出了全部代码--可以复现--亲测有效 :) [ 代码为图片--> 强制自己去敲一次 又不多] 1.打开网站: 2.利用id去定位到我们要进行输入的内容(bing可以直接进行搜索,而csdn需要登录,所以我们用csdn做演示&…

HODL、FUD、FOMO 等其他比特币俚语是什么意思?

作者:Paxful Team 1、FOMO(惧怕错失机会) FOMO 是惧怕错失机会的缩写,可用于日常生活。它指的是当其他人都在谈论比特币时,产生的购买比特币的紧迫感。 2、Shill(不断推广吹捧) Shilling 是指…

linux支持vGPU方案

1,查询gpu型号:lspci | grep "NVIDIA\|VGA" PCI Devices 2,下载驱动 官方驱动 | NVIDIA 3,安装 sudo sh NVIDIA-Linux-x86_64-440.118.02.run -no-x-check -no-nouveau-check -no-opengl-files参数说明: …

自定义View-旋转变色圆角三角形的绘制

本文字数:3151字 预计阅读时间:20分钟 在现代设计中,动效图在APP的UI界面中所起到的作用无疑是显著的。相比于静态的界面,动效更符合人类的自然认知体系,它有效地降低了用户的认知负载,UI动效俨然已经成为了…

汽车新四化,会发生什么?

北京国际汽车展览会正如火如荼地进行中,作为国内外汽车行业瞩目的盛会,众多车企纷纷亮出了自家的“杀手锏”。 这场汽车的盛宴不仅集中展示了众多汽车品牌的最新技术和产品,更深刻体现了汽车新四化的发展趋势。汽车新四化,即电动化、网联化、…

DS进阶:AVL树和红黑树

一、AVL树 1.1 AVL树的概念 二叉搜索树(BST)虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-…

使用Keil移植工程时修改单片机型号参数

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 当使用Keil对STM32系列单片机开发时,如果使用的是库函数,那么不同型号单片机的工程项目文件是可以直接移植的。只需要按照下面的步骤修改对应的芯片,就可以直接将工程移植过去&a…

JVM垃圾收集器--分区收集器

G1收集器 属性 G1(Garbage-First Garbage Collector)在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。G1 有五个属性:分代、增量、并行、标记整理、STW。 分代 G1收集器 将内部分为多个大小相等的区域&#x…

Java8 Stream常见用法

Stream流的常见用法&#xff1a; 1.利用stream流特性把数组转list集合 //定义一个数组Integer[] array {5,2,1,6,4,3};//通过stream特性把数组转list集合List<Integer> list Arrays.stream(array).collect(Collectors.toList());//打印结果System.out.println(list);…

全球数据爬取的解决方案-国外数据爬取

引言 随着经济的持续低迷和对外贸易的需求扩大&#xff0c;各个公司为了更好的了解海外客户情况&#xff0c;最简单直接的办法就是从全球收集公共的网络数据。 无论是海外电商用户的消费习惯还是训练自己的通用人工智能chatgpt&#xff0c;都是需要海量和多种类型数据的支持。…