Structural adapter mode

Structural mode
These design patterns focus on the combination of classes and objects. The concept of inheritance is used to combine interfaces and define how composite objects get new functions.

Adapter mode

Adapter Pattern is 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 play vlc and mp4 files by using a more advanced audio player.

introduce

Intent: convert the interface of one 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: in software systems, it is often necessary to put some "existing objects" into a new environment, and the interface 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 demand 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 depends on the existing object to realize the desired target interface.

Application examples: 1. American electric appliances are 110V and Chinese electric appliances are 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.

Advantages: no two classes can 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 there are too many such situations in A system, it is tantamount to A disaster. Therefore, if it is not necessary, you can reconstruct the system directly without using the adapter. 2. Since JAVA inherits at most one class, it can only adapt to one adapter class at most, 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.

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 realize this function, we need to create an adapter class that implements the # MediaPlayer # interface # MediaAdapter, and use the # AdvancedMediaPlayer # object to play the required format.

AudioPlayer uses 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.

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

Step 2

Create an entity class that implements the advanced mediaplayer interface.

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

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.

public class AudioPlayer implements MediaPlayer {
   MediaAdapter mediaAdapter; 
 
   @Override
   public void play(String audioType, String fileName) {    
 
      //play mp3 Built in support for 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.

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

 

Tags: Design Pattern

Posted by pipe_girl on Sun, 08 May 2022 03:44:47 +0300