设计模式 - 适配器模式

适配器模式充当两个不兼容接口之间的桥梁.这种类型的设计模式属于结构模式,因为此模式结合了两个独立接口的功能.

此模式涉及单个类,负责连接独立或不兼容接口的功能.一个真实的例子可能是读卡器的情况,它充当存储卡和笔记本电脑之间的适配器.您将存储卡插入读卡器和读卡器插入笔记本电脑,以便通过笔记本电脑读取存储卡.

我们通过以下示例演示使用适配器模式,其中包含音频播放器设备只能播放mp3文件,并希望使用能够播放vlc和mp4文件的高级音频播放器.

实施

我们有一个 MediaPlayer 接口和一个具体的类 AudioPlayer 实现 MediaPlayer 界面.默认情况下, AudioPlayer 可以播放mp3格式的音频文件.

我们有另一个接口 AdvancedMediaPlayer 和实现 AdvancedMediaPlayer的具体类界面.这些类可以播放vlc和mp4格式的文件.

我们想让 AudioPlayer 播放其他格式.为此,我们创建了一个适配器类 MediaAdapter ,它实现了 MediaPlayer 接口,并使用 AdvancedMediaPlayer 对象来播放所需的格式.

AudioPlayer 使用适配器类 MediaAdapter 向其传递所需的音频类型,而不知道可以播放所需格式的实际类. AdapterPatternDemo ,我们的演示类将使用 AudioPlayer 类来播放各种格式.

适配器模式UML图

步骤1

为Media Player和Advanced Media Player创建界面.

MediaPlayer.java

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

AdvancedMediaPlayer.java

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

步骤2

创建实现 AdvancedMediaPlayer 接口的具体类.

VlcPlayer.java

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
   } 
}

Mp4Player.java

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);		
   } 
}

步骤3

创建实现 MediaPlayer的适配器类界面.

MediaAdapter.java

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 界面.

AudioPlayer.java

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");
      }
   } 
}

步骤5

使用AudioPlayer播放不同类型的音频格式.

AdapterPatternDemo.java

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");
   }
}

步骤6

验证输出.

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