Design Pattern 简明教程

Design Patterns - Adapter Pattern

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

Adapter pattern works as a bridge between two incompatible interfaces. This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces.

此模式包含一个单一的类,负责加入独立或不兼容接口的功能。一个实际的示例可以是充当内存卡与笔记本电脑之间适配器的读卡器。将内存卡插入读卡器,再将读卡器插入笔记本电脑,这样就可以通过笔记本电脑读取内存卡。

This pattern involves a single class which is responsible to join functionalities of independent or incompatible interfaces. A real life example could be a case of card reader which acts as an adapter between memory card and a laptop. You plugin the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.

我们通过以下示例展示适配器模式的使用,其中音频播放器设备只能播放 mp3 文件,并且想使用能够播放 vlc 和 mp4 文件的高级音频播放器。

We are demonstrating use of Adapter pattern via following example in which an audio player device can play mp3 files only and wants to use an advanced audio player capable of playing vlc and mp4 files.

Implementation

我们有一个 MediaPlayer 接口和实现了该 MediaPlayer 接口的具体类 AudioPlayer。AudioPlayer 能够默认播放 mp3 格式的音频文件。

We have a MediaPlayer interface and a concrete class AudioPlayer implementing the MediaPlayer interface. AudioPlayer can play mp3 format audio files by default.

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

We are having another interface AdvancedMediaPlayer and concrete classes implementing the AdvancedMediaPlayer interface. These classes can play vlc and mp4 format files.

我们希望让 AudioPlayer 也播放其他格式。为了实现这一点,我们创建了一个适配器类 MediaAdapter,实现了 MediaPlayer 接口,并使用 AdvancedMediaPlayer 对象播放必需的格式。

We want to make AudioPlayer to play other formats as well. To attain this, we have created an adapter class MediaAdapter which implements the MediaPlayer interface and uses AdvancedMediaPlayer objects to play the required format.

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

AudioPlayer uses the adapter class MediaAdapter passing it the desired audio type without knowing the actual class which can play the desired format. AdapterPatternDemo, our demo class will use AudioPlayer class to play various formats.

adapter pattern uml diagram

Step 1

为媒体播放器和高级媒体播放器创建接口。

Create interfaces for Media Player and 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);
}

Step 2

创建实现了 AdvancedMediaPlayer 接口的具体类。

Create concrete classes implementing the AdvancedMediaPlayer interface.

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

Step 3

创建实现了 MediaPlayer 接口的适配器类。

Create adapter class implementing the MediaPlayer interface.

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

Step 4

创建实现了 MediaPlayer 接口的具体类。

Create concrete class implementing the MediaPlayer interface.

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

Step 5

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

Use the AudioPlayer to play different types of audio formats.

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

Step 6

验证输出。

Verify the output.

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