适配器主要解决适配问题,即将一些由于接口不兼容不能一起工作的类可以在一起工作。
例如插座上是220v的电压,手机充电需要5v的电压,这时手机和插座直接就通过一个适配器(充电器)连接起来了。
例如一个音频播放器只能播放MP3格式的文件,我们通过一个适配器将其连接到高级播放器上,
当前音频播放器不支持的格式(MP4、VLC)转交给高级播放器播放,使其能播放更多格式。
下面就媒体播放器这个例子看下对应代码:
媒体文件类型
public enum AudioTypeEnum { MP3,VLC,MP4 }
高级媒体播放器接口,可以播放MP4/VLC格式的文件。后续高级媒体播放器与媒体播放器通过适配器连接,使媒体播放器可以支持更多格式。
这个接口和实现类可以暂且不看,等后续添加适配器的时候再看这一部分。
public interface AdvanceMediaPlay { public void playMp4(String fileName); public void playVlc(String fileName); }
高级媒体播放器 播放MP4格式文件的具体实现类
public class Mp4Play implements AdvanceMediaPlay{ @Override public void playMp4(String fileName) { System.out.println("play mp4:" + fileName); } @Override public void playVlc(String fileName) {} }
高级媒体播放器 播放VLC格式的具体实现类
public class VlcPlay implements AdvanceMediaPlay{ @Override public void playMp4(String fileName) {} @Override public void playVlc(String fileName) { System.out.println("play vlc:" + fileName); } }
(上述部分可暂且忽略,等后续添加适配器时再查看)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
媒体播放器接口,主要包含播放方法,方法参数:媒体文件类型(MP3、MP4、VLC),文件名
public interface MediaPlay { public void paly(AudioTypeEnum audioType, String fileName); }
实现媒体播放接口的音频播放器,音频播放器只能实现播放MP3格式的文件。
public class AudioPlay implements MediaPlay{ //private MediaAdapter mediaAdapter; public void paly(AudioTypeEnum audioType, String fileName) { switch(audioType) { case MP3://内置MP3播放器 System.out.println("play mp3:" + fileName); break; case MP4://TODO 其他可播放类型,采用适配器播放 default://TODO 无法播放部分抛出异常 try { throw new Exception("播放异常,格式不支持!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
我们先来看下没有添加适配器,只能播放MP3格式的情况,此时将高级媒体播放器看做与其无关的一个个体。
目前有两个个体,一个是音频播放器,一个是高级媒体播放器。
测试音频播放器
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub MediaPlay mediaPlay = new AudioPlay(); mediaPlay.paly(AudioTypeEnum.MP4, "mmm4"); mediaPlay.paly(AudioTypeEnum.MP3, "mmm3"); mediaPlay.paly(AudioTypeEnum.VLC, "fff"); } }
java.lang.Exception: 播放异常,格式不支持! play mp3:mmm3 at com.design.adapter.AudioPlay.paly(AudioPlay.java:20) at com.design.adapter.Main.main(Main.java:8) java.lang.Exception: 播放异常,格式不支持! at com.design.adapter.AudioPlay.paly(AudioPlay.java:20) at com.design.adapter.Main.main(Main.java:10)
可以看到,只有音频播放器支持的MP3格式可以正常播放,其他格式都无法播放。
此时有一个高级媒体播放器可以播放其他类型的媒体文件,我们有没有什么办法将音频播放器和高级媒体播放器联系起来?
当然有,那就是适配器。
现在我们想通过一个适配器将两者联系起来,让音频播放器可以通过高级媒体播放器播放更多类型的信息。
既然适配器是对传入音频播放器的文件进行适配,将其适配到高级媒体播放器中播放,那么首先适配器需要和音频播放器一样实现MediaPlay接口。
public class MediaAdapter implements MediaPlay{ public MediaAdapter(AudioTypeEnum audioTypeEnum) { } @Override public void paly(AudioTypeEnum audioType, String fileName) { } }
适配器最终是调用高级媒体播放器播放文件,最终播放具体文件还是高级媒体播发器接口的实现类来完成的。
所有在创建适配器对象时,我们可以根据文件类型,实例化一个播放该文件的播放器。
public class MediaAdapter implements MediaPlay{ AdvanceMediaPlay advanceMediaPlay; //根据类型,适配对应对象,最后通过具体对象播放文件 public MediaAdapter(AudioTypeEnum audioTypeEnum) { switch (audioTypeEnum) {//是什么类型的对象,就实例化什么类型的播放器 case MP4:advanceMediaPlay = new Mp4Play(); break; case VLC:advanceMediaPlay = new VlcPlay(); break; default: try { throw new Exception("播放类型异常!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //根据类型,适配对应方法 @Override public void paly(AudioTypeEnum audioType, String fileName) { } }
具体的播放对象实例完成后,我们来看看paly方法,现在确定了基本的思路。音频播放器将不支持的文件传递给适配器,
适配器调用对应的播放器来播放文件。
AdvanceMediaPlay 中有playMp4和palyVlc两个播放方法,这时在适配器的paly中需要根据文件类型,调用对用的方法。
例如实例化适配器时传递进来的文件类型是MP4,实例的是播放MP4的播放器,调用play方法时调用的应该是palyMp4。
在播放MP4格式的播放器中调用playVlc方法显然是不正确的。
public class MediaAdapter implements MediaPlay{ AdvanceMediaPlay advanceMediaPlay; //根据类型,适配对应对象 public MediaAdapter(AudioTypeEnum audioTypeEnum) { switch (audioTypeEnum) {//根据文件类型,实例化对应类型播放器 case MP4:advanceMediaPlay = new Mp4Play(); break; case VLC:advanceMediaPlay = new VlcPlay(); break; default: try { throw new Exception("播放类型异常!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //根据类型,适配对应方法 @Override public void paly(AudioTypeEnum audioType, String fileName) { switch(audioType) {//根据文件类型调用对应方法 case MP4: advanceMediaPlay.playMp4(fileName); break; case VLC: advanceMediaPlay.playVlc(fileName); break; default: try { throw new Exception("播放异常!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
适配器完成后,我们就在音频播放器中添加上适配器
public class AudioPlay implements MediaPlay{ private MediaAdapter mediaAdapter;//适配器 public void paly(AudioTypeEnum audioType, String fileName) { // TODO Auto-generated method stub switch(audioType) { case MP3://内置MP3播放器 System.out.println("play mp3:" + fileName); break; case MP4://TODO 其他可播放类型,采用适配器播放 case VLC: mediaAdapter = new MediaAdapter(audioType);//实例化适配器,适配器会根据类型实例化对应播放器 mediaAdapter.paly(audioType, fileName);//播放时,会根据对应播放器调用对应方法。 break; default://TODO 无法播放部分抛出异常 try { throw new Exception("播放异常,格式不支持!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
测试添加适配器后的音频播放器
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub MediaPlay mediaPlay = new AudioPlay(); mediaPlay.paly(AudioTypeEnum.MP4, "mmm4"); mediaPlay.paly(AudioTypeEnum.MP3, "mmm3"); mediaPlay.paly(AudioTypeEnum.VLC, "fff"); } }
运行结果:
play mp4:mmm4
play mp3:mmm3
play vlc:fff
参考资料: