转换一个存在的接口到一个新的接口,以完成不相关的类的兼容性和重用性,这种模式叫做适配器模式。这个模式也被称为封装(wrapper)模式,适配器模式是属于结构设计模式之一。
适用场合和优势:
- 尝试去匹配一个接口(WindowAdapter等)
- 使不相关的类工作在一起
- 多兼容性融合
- 提高类的透明性
- 制作可插入的套件(pluggable kit)
- 委托对象
- 更高级类的重用
相关的代理(proxy)模式, 提供了作为它的客体的相同接口,而一个适配器模式提供了一个不同的接口来适配这个对象;装饰模式, 它关注于为对象添加新功能,而一个适配器模式协调两个不同的对象;桥接模式,它尝试着从它的实现和生产一个独立且不同的对象中分离出一个接口,而一个适配器则尝试着去改变和协调一个对象的接口。
适配器模式可以使用继承或是组合方式实现,实现方法不同,但是目的和解决方案是一样的。
经典的UML类图如下:
根据一个具体的实例来阐明什么是工厂模式。我们有一个接口MediaPlayer和一个具体的音频播放器实现 MediaPlayer接口。AudioPlayer默认情况下能够播放mp3格式的音频文件。 我们也有另一个AdavnacedMediaPlayer接口和它的实现类AdvancedMediaPlayer,这个类能够播放vlc和mp4格式的音频文件。现在,我们想AudioPlayer也能够播放其它格式(mp4和vlc)文件。为了达到这个目的, 我需要创建一个适配器类MediaPlayer来实现MediaPlayer接口,组合使用AdvancedMediaPlayer类以达到能够播放需要的格式的目的。AudioPlayer使用了适配器类MediaAdapter传入给它音频类型,不需要知道事实上那个类能够播放这个格式的文件。最后,使用AdapterPatternDemo测试这个设计模式。UML类图如下所示:
接口MediaPlayer, AdvanceAudioPlayer的定义。
public interface MediaPlayer {
public void play(String audioType, String fileName) ;
}
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
AudioPlayer的具体实现。
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
//inbuilt support to play mp3 music files
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: "+ fileName);
}
//mediaAdapter is providing support to play other file formats
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");
}
}
}
高级音频播放器的具体实现。
public class Mp4Player implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
//do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ 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) {
//do nothing
}
}
定义是一个适配器,适配高级音频播放器功能。
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);
}
}
}
正如AudioPlayer代码展示的,只需要调用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");
}
}
运行结果:
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported