适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。
优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。
缺点: 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
类图:
代码:
一、创建一般媒体播放器的接口和更高级媒体播放器的接口
1 public interface MediaPlayer { 2 public void play(String type,String filename); 3 }
1 public interface AdvancedMediaPlayer { 2 public void playVlc(String filename); 3 public void playMp4(String filename); 4 }
二、创建了实现更高级媒体播放器接口的实体类
1 public class Mp4Player implements AdvancedMediaPlayer { 2 3 @Override 4 public void playVlc(String filename) { 5 6 7 } 8 9 @Override 10 public void playMp4(String filename) { 11 System.out.println("Playing MP4 file name:"+filename); 12 } 13 14 }
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) { // TODO Auto-generated method stub } }
三、创建适配器类,实现了想扩充功能的那个类的接口,内部依赖于扩充的接口的实体类的对象
1 public class MediaAdapter implements MediaPlayer { 2 3 AdvancedMediaPlayer aa; 4 5 6 public MediaAdapter(String filetype) { 7 if(filetype.equalsIgnoreCase("vlc")){ 8 aa = new VlcPlayer(); 9 }else if(filetype.equalsIgnoreCase("MP4")){ 10 aa = new Mp4Player(); 11 } 12 } 13 14 @Override 15 public void play(String type,String filename) { 16 if (type.equalsIgnoreCase("vlc")) { 17 aa.playVlc(filename); 18 }else if (type.equalsIgnoreCase("MP4")) { 19 aa.playMp4(filename); 20 } 21 22 } 23 24 }
四、创建实现了一般媒体播放器接口的实体类,内部通过适配器来增加功能
1 public class AudioPlayer implements MediaPlayer { 2 3 MediaAdapter adapter; 4 5 @Override 6 public void play(String type,String filename) { 7 if (type.equalsIgnoreCase("MP3")) { 8 System.out.println("Playing mp3 file name:"+filename); 9 }else if (type.equalsIgnoreCase("MP4")) { 10 adapter = new MediaAdapter(type); 11 adapter.play(type, filename); 12 }else if (type.equalsIgnoreCase("vlc")) { 13 adapter = new MediaAdapter(type); 14 adapter.play(type, filename); 15 }else { 16 System.out.println("sorry,I can't play"); 17 } 18 } 19 20 }
五、测试
1 public class AdapterPatternDemo { 2 3 public static void main(String[] args) { 4 AudioPlayer audioPlayer = new AudioPlayer(); 5 6 audioPlayer.play("vlc", "hhh"); 7 audioPlayer.play("MP3", "333"); 8 audioPlayer.play("MP4", "444"); 9 audioPlayer.play("gif", "ttt"); 10 } 11 12 }