アダプターモード


アダプター パターンは、互換性のない 2 つのインターフェイス間のブリッジとして機能します。このタイプのデザイン パターンは、2 つの独立したインターフェイスの機能を組み合わせた構造パターンです。

このパターンには、独立した、または互換性のないインターフェイス機能の追加を担当する単一のクラスが含まれます。実際の例を挙げると、カード リーダーはメモリ カードとノートブックの間のアダプタとして機能します。メモリ カードをカード リーダーに挿入し、次にカード リーダーをノートブックに挿入すると、ノートブックからメモリ カードを読み取ることができます。

次の例を通じてアダプター パターンの使用方法を示します。このうち、オーディオ プレーヤー デバイスは、より高度なオーディオ プレーヤーを使用して vlc および mp4 ファイルを再生することにより、mp3 ファイルのみを再生できます。

はじめに

目的: クラスのインターフェースを顧客が望む別のインターフェースに変換します。アダプター パターンを使用すると、インターフェイスに互換性がないために連携できないクラスを連携させることができます。

主な解決策: 主にソフトウェア システムで解決され、多くの場合、いくつかの「既存のオブジェクト」を新しい環境に配置する必要があり、新しい環境で必要なインターフェイスは既存のオブジェクトでは満たされません。

いつ使用するか: 1. システムは既存のクラスを使用する必要がありますが、このタイプのインターフェイスはシステムのニーズを満たしません。 2. 将来導入される可能性のあるクラスなど、相互にあまり関係のないいくつかのクラスを操作するために再利用できるクラスを作成したい。これらのソース クラスには、必ずしも一貫したインターフェイスがあるとは限りません。 3. インターフェイス変換を通じてクラスを別のクラスに挿入します。 (たとえば、トラと鳥にはフライング タイガーが追加されました。エンティティを追加する必要がなく、アダプターを追加してタイガー オブジェクトを含めてフライング インターフェイスを実装します。)

解決方法: 継承または依存関係 (推奨)。

キーコード: アダプターは、必要なターゲットインターフェイスを実現するために既存のオブジェクトを継承または依存します。

応用例: 1. アメリカの電化製品は110V、中国は220Vです。110Vを220Vに変換するアダプターが必要です。 2. JAVA JDK 1.1 は Enumeration インターフェイスを提供し、1.2 は Iterator インターフェイスを提供します。1.2 JDK を使用する場合は、以前のシステムの Enumeration インターフェイスを Iterator インターフェイスに変換する必要があります。この場合、アダプター モードが必要です。 。 3. LINUX 上で WINDOWS プログラムを実行します。 4.JAVAのjdbc。

利点: 1. 無関係な 2 つのクラスを一緒に実行できます。 2. クラスの再利用が改善されました。 3. クラスの透明性が向上しました。 4. 優れた柔軟性。

短所: 1. アダプターを過度に使用すると、システムが非常に乱雑になり、全体を把握するのが難しくなります。たとえば、A インターフェイスが呼び出されていることは明らかですが、実際には B インターフェイスの実装に内部的に適合しています。これがシステム内で頻繁に発生すると、それは災害に相当します。したがって、必要がなければアダプタを使用せずに直接システムを再構築することも可能です。 2. JAVA は最大 1 つのクラスを継承するため、最大 1 つのアダプタ クラスにのみ適応でき、ターゲット クラスは抽象クラスである必要があります。

使用シナリオ: 通常に実行されているシステムのインターフェイスを変更する動機がある場合は、アダプター パターンの使用を検討する必要があります。

注: アダプターは詳細設計中に追加されるのではなく、サービス中のプロジェクトの問題を解決するために追加されます。

実装

MediaPlayerインターフェースと、MediaPlayerインターフェースを実装するエンティティクラスAudioPlayerがあります。デフォルトでは、AudioPlayer は mp3 形式のオーディオ ファイルを再生できます。

別のインターフェイス AdvancedMediaPlayer と、AdvancedMediaPlayer インターフェイスを実装するエンティティ クラスもあります。このクラスは、vlc および mp4 形式のファイルを再生できます。

AudioPlayerで他の形式のオーディオファイルを再生したいと考えています。この機能を実装するには、MediaPlayer インターフェースを実装するアダプター クラス MediaAdapter を作成し、AdvancedMediaPlayer オブジェクトを使用して必要な形式を再生する必要があります。

AudioPlayer アダプター クラス MediaAdapter を使用して、必要な形式でオーディオを再生できる実際のクラスを知らなくても、必要なオーディオ タイプを渡します。 AdapterPatternDemo のデモ クラスは、AudioPlayer クラスを使用してさまざまな形式を再生します。

适配器模式的 UML 图

ステップ 1

メディア プレーヤーおよびより高度なメディア プレーヤーのインターフェイスを作成します。

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) {
      //什么也不做
   }
}

Mp4Player.java

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 インターフェースを実装するアダプター クラスを作成します。

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) {		

      //播放 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 を使用して、さまざまなタイプのオーディオ形式を再生します。

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

出力を確認します。

りー