Adapter pattern of design pattern

1. Adapter mode

The Adapter Pattern serves as a bridge between two incompatible interfaces. This type of design pattern belongs to structural pattern, which combines the functions of two independent interfaces.

This pattern involves a single class that is responsible for adding independent or incompatible interface functions. For a real example, the card reader is used as an adapter between the memory card and the notebook. You insert the memory card into the card reader, and then insert the card reader into the notebook, so that you can read the memory card through the notebook.

We use the following example to demonstrate the use of the adapter pattern. Among them, the audio player device can only play mp3 files, and vlc and mp4 files can be played by using a more advanced audio player.

2. Introduction

Intent: convert the interface of a class into another interface that the customer wants. The adapter pattern allows classes that cannot work together because of interface incompatibility to work together.

Main solution: it mainly solves that in software systems, some "existing objects" often need to be put into a new environment, and the interfaces required by the new environment cannot be met by the existing objects.

When to use:

1. The system needs to use existing classes, and such interfaces do not meet the needs of the system.
2. You want to create a reusable class to work with some classes that are not closely related to each other, including some classes that may be introduced in the future. These source classes do not necessarily have consistent interfaces.
3. Insert one class into another class family through interface conversion. (for example, tigers and birds, now there is a flying tiger. Without increasing the requirements of entities, an adapter is added to contain a tiger object and realize the flying interface.)

How to solve: inheritance or dependency (recommended).

Key code: the adapter inherits or relies on existing objects to implement the desired target interface.

Application example:

1. American electric appliance 110V, China 220V, there must be an adapter to convert 110V into 220V.
2. JAVA JDK 1.1 provides the Enumeration interface, while 1.2 provides the Iterator interface. If you want to use the 1.2 JDK, you need to convert the Enumeration interface of the previous system into the Iterator interface. At this time, you need the adapter mode.
3. Run WINDOWS program on LINUX.
4. jdbc in JAVA.

advantage:

1. You can let any two classes that are not associated run together.
2. Class reuse is improved.
3. Increased class transparency.
4. Good flexibility.

Disadvantages:

1. Excessive use of adapters will make the system very messy and difficult to grasp as A whole. For example, it is obvious that the A interface is called, but in fact, it is internally adapted to the implementation of B interface. If this happens too often in A system, it is tantamount to A disaster. Therefore, if it is not necessary, you can refactor the system directly instead of using adapters.
2. Since JAVA inherits at most one class, at most one adapter class can be adapted, and the target class must be an abstract class.

Usage scenario: if you are motivated to modify the interface of a normal system, you should consider using the adapter mode.

Note: adapters are not added during detailed design, but solve the problems of projects in service.

3. Realization

We have a MediaPlayer interface and an entity class AudioPlayer that implements the MediaPlayer interface. By default, AudioPlayer can play mp3 format audio files.

We also have another interface, AdvancedMediaPlayer, and an entity class that implements the AdvancedMediaPlayer interface. This class can play files in vlc and mp4 formats.

We want AudioPlayer to play audio files in other formats. To achieve this function, we need to create an adapter class MediaAdapter that implements the MediaPlayer interface and use the AdvancedMediaPlayer object to play the required format.

AudioPlayer uses the adapter class MediaAdapter to transfer the required audio type without knowing the actual class that can play the audio in the required format. The AdapterPatternDemo class uses the AudioPlayer class to play various formats.

Step 1
Create interfaces for media players and more advanced media players.

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
Create an entity class that implements 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
Create an adapter class that implements 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
Create an entity class that implements the MediaPlayer interface.

AudioPlayer.java
public class AudioPlayer implements MediaPlayer {
   MediaAdapter mediaAdapter; 
 
   @Override
   public void play(String audioType, String fileName) {    
 
      //Built in support for playing mp3 music files
      if(audioType.equalsIgnoreCase("mp3")){
         System.out.println("Playing mp3 file. Name: "+ fileName);         
      } 
      //mediaAdapter provides support for playing 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
Use 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
Execute the program and output the results:

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

Keywords: Java Design Pattern

Added by rocky on Fri, 21 Jan 2022 21:03:30 +0200