下图为所有设计模式,带标记为重点掌握以及工作中常用到的:
适配器模式属于结构型模式之一,顾名思义,肯定会存在一个适配器的类去进行适配。比如我们以前的笔记本电脑如果要读取我们手机的内存卡,直接读取是不可以的。如果要读取的话我们需要准备一个读卡器,将内存卡装入到读卡器中,然后将读卡器插入到电脑,这样子才可以完成内存卡的读取。其中读卡器就充当着我们所说的适配器这个角色,适配器模式是作为两个不兼容的接口之间的桥梁
模式名称 | 优点 | 缺点 | 应用场景 |
---|---|---|---|
适配器模式 | 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。 | 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。 | 有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。 |
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
接下来我们举例来说明适配器模式,让大家可以有更好的理解:
假设我们现在有个普通播放器,只可以播放mp3文件,不能播放其它类型的文件,然后我们还有个高级播放器,可以播放vlc 和 mp4 文件。那么如果我想要普通播放器能够同时支持这3种类型的文件,该如何做呢?
适配器模式
1、创建一个普通播放器和一个高级播放器接口
/**
* 媒体播放器接口
*
* @author wyj
* @date 2022/1/23 10:37
*/
public interface MediaPlayer {
void play(String audioType, String fileName);
}
/**
* 高级媒体播放器接口
*
* @author wyj
* @date 2022/1/23 10:37
*/
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
2、创建高级播放器的2个实现类
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
// 什么也不做
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// 什么也不做
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
3、为普通播放器创建适配器类
适配器类中持有高级播放器的对象:
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();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
4、创建普通播放器实现类
播发器实现类中持有适配器类的对象:
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
// 播放 mp3 音乐文件的内置支持
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
}
// mediaAdapter 提供了播放其他文件格式的支持
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");
}
}
}
5、测试
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");
}
6、测试结果
小结
根据以上案例,我们就实现了普通播放器拥有高级播放器的功能,仅仅是在中间添加了一个适配器类。这种设计模式在工作中,我也没有遇到过,可能现在理解到了,但是不一定会使用,在此记录一下,相信我以后可能会用到的。