目录
第二步:创建实现了 AdvancedMediaPlayer 接口的实体类。
第五步:测试类,使用 AudioPlayer 来播放不同类型的音频格式
适配器模式相关介绍
适配器模式是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。适配器模式允许不兼容的接口之间进行合作。
在软件开发中,当我们需要使用一个已经存在的类而其接口与我们所需的接口不匹配时,适配器模式就派上用场了。适配器模式通过创建一个适配器类,该适配器类实现了目标接口,并持有一个被适配类的对象。适配器类通过调用被适配类的方法来实现目标接口的方法,从而将被适配类的接口转换成目标接口。
适配器模式的主要角色包括:
-
目标接口(Target Interface):定义客户端所期望的接口。
-
被适配者(Adaptee):已经存在的类,其接口与目标接口不匹配。
-
适配器(Adapter):实现目标接口,并持有被适配者的对象。在适配器中,通过调用被适配者的方法来实现目标接口的方法。
适配器模式的工作原理如下:
-
客户端通过调用目标接口的方法来与适配器进行交互。
-
适配器接受客户端的请求,并将其转发给被适配者。
-
被适配者执行相应的操作,并将结果返回给适配器。
-
适配器将被适配者的结果进行适当的处理,然后返回给客户端。
适配器模式的优点包括:
-
解决接口不匹配问题:适配器模式可以在现有的类之间提供一个无缝的接口转换,使它们可以协同工作。
-
复用现有代码:适配器模式允许我们重用已经存在的类,而无需修改其源代码。
-
提高灵活性:通过适配器模式,我们可以在系统中引入新的类,并与已有类进行适配,从而提高系统的灵活性和可扩展性。
适配器模式的缺点包括:
-
增加了类的数量:使用适配器模式会增加代码的复杂性,因为需要引入适配器类。
-
可能引入冗余代码:有时候适配器类可能只是简单地委派调用给被适配者,这可能引入一些冗余的代码。
适配器实例
有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。
AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。
设计的类图
第一步:为媒体播放器和更高级的媒体播放器创建接口
public interface MediaPlayer {
public void play(String audioType, String fileName);
}
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
第二步:创建实现了 AdvancedMediaPlayer 接口的实体类。
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 VlcPlayer implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: "+ fileName);
}
@Override
public void playMp4(String fileName) {
//什么也不做
}
}
第三步:创建实现了 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();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
第四步:创建实现了 MediaPlayer 接口的实体类
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");
}
}
}
第五步:测试类,使用 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");
}
}