适配器模式(Adaptor Pattern)是作为两个不兼容接口的桥梁,这种设计模式属于结构型射界模式,它结合了两个独立接口的功能。这种模式设计到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是内存卡和笔记本之间的适配器。
介绍
意图 :
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本的由于接口不兼容而不能一起工作的类可以一起工作。
主要解决:
主要解决在软件系统中,常常要将一些现存的对象放到新环境中,而新环境要求的接口是现对象不能满足的。
何时使用:
1.系统需要使用现有的类,而此类的接口不符合系统的要求;2.想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关系的一些类,包括一些将来可能引进的类,这些源类不一定有一致的接口;3.通过接口转换,将一个类插入另一个类系中。(比如,老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,包含一个虎对象,实现飞的接口)。
如何解决:
适配器继承或依赖已有的对象,实现接口。
应用实例:
1.电源适配器;2.JDK1.1提供了Enumeration接口,1.2提供了Iterator接口,想要使用1.2JDK,就用到了适配器;3.LINUX运行Windows程序;4.jdbc。
优点:
可以让任何没有关系的类一起运行;提高了服用型;增加类的透明度;灵活性好。
缺点:
过多的使用适配器,会让系统非常凌乱,不易整体把握。比如,明明看到是调用A接口,其实内部被适配成了B接口的实现,一个系统出现太多这样的情况,无异于异常灾难,没有必要,应该直接重构系统;
JAVA单继承,只能适配一个适配者类,目标类必须是抽象类。
使用场景:
有动机的修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:
适配器不是在设计时添加的,而是解决正在服役的项目问题。
目标功能接口
package com.adaptor.playerinterface;
public interface AdvancedMediaPlayer {
void playVlc(String filename);
void playMp5(String filename);
}
已有功能接口
package com.adaptor.playerinterface;
public interface MediaPlayer {
public abstract void play(String audioPlay,String fileName);
}
两个接口的实现类
package com.adptor.entity;
import com.adaptor.playerinterface.MediaPlayer;
import com.adptor.adptors.MediaAdaptor;
public class AudioPlayer implements MediaPlayer{
private MediaPlayer mp;
@Override
public void play(String audioPlay, String fileName) {
//mp3是内置支持的
if(audioPlay.equalsIgnoreCase("mp3")){
System.out.println("play "+fileName+"."+audioPlay);
}else if(audioPlay.equalsIgnoreCase("vlc") || audioPlay.equalsIgnoreCase("mp5")){
mp = new MediaAdaptor(audioPlay);
mp.play(audioPlay,fileName);
}else{
System.out.println("unknown format");
}
}
}
package com.adptor.entity;
import com.adaptor.playerinterface.AdvancedMediaPlayer;
public class Mp5Player implements AdvancedMediaPlayer{
@Override
public void playVlc(String filename) {
}
@Override
public void playMp5(String filename) {
System.out.println("play "+filename+".mp5");
}
}
package com.adptor.entity;
import com.adaptor.playerinterface.AdvancedMediaPlayer;
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String filename) {
System.out.println("play "+filename+".vlc");
}
@Override
public void playMp5(String filename) {
}
}
适配器类
package com.adptor.adptors;
import com.adaptor.playerinterface.AdvancedMediaPlayer;
import com.adaptor.playerinterface.MediaPlayer;
import com.adptor.entity.Mp5Player;
import com.adptor.entity.VlcPlayer;
public class MediaAdaptor implements MediaPlayer{
private AdvancedMediaPlayer amp;
public MediaAdaptor(String audioType){
if(audioType.equalsIgnoreCase("vlc")){
amp = new VlcPlayer();
}else if(audioType.equalsIgnoreCase("mp5")){
amp = new Mp5Player();
}
}
@Override
public void play(String audioPlay, String fileName) {
if(audioPlay.equalsIgnoreCase("vlc")){
amp.playVlc(fileName);
}else if(audioPlay.equalsIgnoreCase("mp5")){
amp.playMp5(fileName);
}
}
}
测试类
package com.adaptor.test;
import org.junit.Test;
import com.adptor.entity.AudioPlayer;
public class TestDemo {
@Test
public void test(){
AudioPlayer ap = new AudioPlayer();
ap.play("mp3","Numb");
ap.play("mp5","Hello");
ap.play("vlc","Passion");
ap.play("flv","Glad");
}
}
输出打印
play Numb.mp3
play Hello.mp5
play Passion.vlc
unknown format