Fork me on GitHub

设计模式 - 适配器

注意:所有文章除特别说明外,转载请注明出处.

简介

适配器模式是作为两个不兼容接口之间的桥梁,它结合了两个独立接口的功能。这里的适配器模式和代理模式相像。

1.适配器模式表示有一个接口需要实现,但现成对象不满足,需要加一层适配器来进行适配。

默认适配器模式
类适配器模式
对象适配器模式

提示:类适配器和对象适配器的异同:一个采用继承,一个采用组合。类适配器属于静态实现,对象适配器属于动态实现,对象适配需要多实例化一个对象。对象适配器用得比较多。

通过继承的方法,适配器自动获得了所需要的大部分方法。

适配器模式

1.为媒体播放器和更高级的媒体播放器创建接口

public interface MediaPlayer {
   public void play(String audioType, String fileName);
}

public interface AdvancedMediaPlayer { 
   public void playVlc(String fileName);
   public void playMp4(String fileName);
}

2.创建实现 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 Mp4Player implements AdvancedMediaPlayer{

   @Override
   public void playVlc(String fileName) {
      //什么也不做
   }

   @Override
   public void playMp4(String fileName) {
      System.out.println("Playing mp4 file. Name: "+ fileName);      
   }
}

3.创建实现 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);
      }
   }
}

4.创建实现 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");
      }
   }   
}

5.使用 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");
   }
}

总结

如果一个类需要实现此类没有的功能,而其它类有的功能,这时候就可以实现一个该类的适配器类,使用其它类的对象来实现其功能。

提示:适配器模式和代理模式的区别(比较对象适配器模式和代理模式):
1.代理模式是增强原方法,而适配器是提供”将狗包装成鸭,然后当做鸭来用””。狗和鸭之间原本没有继承关系。

适配器模式引入一个被称为适配器的包装类,它所包装的对象称为适配者。将一个接口转换成希望的另一个接口,是接口不兼容的哪些类一起工作。

本文标题:设计模式 - 适配器

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:23:51

原始链接:http://bangjinhu.github.io/undefined/设计模式 - 适配器模式 - 重点/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.