Article Structure – What are adapter patterns – Meaning – Solutions – Key code – Examples – Explanations – Diagrams

What is the adapter pattern

As the name suggests, the adapter pattern is that two incompatible interface adapter and compatibility between, at the same time, this model is also two incompatible interface link bridge, the model belongs to structural, this pattern is a combination of two independent interface functions, for example, on your computer a built-in player, can only play mp4 video player, If one day you need to play mp3 audio, you can use your computer’s video player (there is no adapted mode for this feature) so that the video player can play MP3 audio

meaning

The functions of an interface are converted to the functions required by Party A, so that functions that cannot be combined before are integrated into one interface

To solve

Mainly to solve the software in the background, the method of object in A project or in A new environment, and the new environment or project interface can’t meet the demand of the original object in the project (if have the function of play mp4 video B have the function of play Mp3, so when A need to Mp3, but no Mp3 decoder, can use the adapter pattern, at this time An Mp3 adapter is provided in Mp4.

The key code

The adapter inherits or relies on existing objects to implement the desired functionality of the target interface

advantages

You can run two classes that are not strictly related to each other, improving code performance, increasing class transparency, and greater flexibility, as well as good decoupling, reducing dependencies between objects

disadvantages

The disadvantages are obvious. Excessive use of adapters will make it difficult to operate logic in A class and maintain subsequent code. When A code is called, use adapters to adapt to B code so that A project is called, if more A->B->C->D… That leaves you in an unmaintainable state, and when any of these rings change, your code will have problems, so the adapter pattern should be used appropriately

The instance

Step 1: Create a media player and an advanced media player, in which the media player exists as an adaptation method and the advanced media player provides the presence of specified methods

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);
}
Copy the code

Step 2: create an interface implementation class for advanced media player, which implements the functions of Vlc and Mp4, but the concrete class has only specific functions, which implements the functions of advanced media player

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); }}Copy the code

Step 3: Create an adapter class that implements the MediaPalyer interface, the MediaPlayer interface of Step 1, and implement the Player method to use as the adapter method, and the rest as the normal AdvancedMediaPlayer two VLP and MP4 methods

MediaAdapter.java
public class MediaAdapter implements MediaPlayer {
    // Introduction of advanced media player (VLC && MP4)
    AdvancedMediaPlayer advancedMusicPlayer;
    
    //AdvancedMediaPlayer constructor, which provides a function initialization field to create an object
    public MediaAdapter(String audioType){
        if(audioType.equalsIgnoreCase("vlc") ){
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")){
            advancedMusicPlayer = newMp4Player(); }}// This method comes from MediaPalyer, the original media player class
    // This method acts as an adapter method, invoking the specified method with a name and constructor
    @Override
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("vlc")){
            advancedMusicPlayer.playVlc(fileName);
        }else if(audioType.equalsIgnoreCase("mp4")){ advancedMusicPlayer.playMp4(fileName); }}}Copy the code

Step 4: Create an implementation class for the MediaPalyer interface. Palyer of this class is an adaptation method. If Vlc or Mp4 is passed in, you can create an adapter class.

AudioPlayer.java
public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;
    
    // This method is used for
    @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"); }}}Copy the code

Step 5: use AudioPalyer to play different formats of audio formats, the logic of the method call If is the mp3 player is the default built-in playback method, if the mp4 | | VLC method, then use adapter to create advanced media player method, if is avi is direct filtering method of the player

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

Output result:

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
Copy the code

Explanation:

Adapter pattern, the entire process and logic from the bottom up, started from the Demo adapter pattern, if the incoming is mp3 is own playback method, do not use the adapter class for adapter, if you are using mp4 | | VLC player at the time of call player method, create media adapter class, At the same time, the media player class initializes the corresponding object VlcPalyer | | Mp4Player or object, the two objects inherited AdvanceMediaPlayer bring play function, In the AudioPlayer class, the adapter class calls the player and passes in the type and fileName. In this case, the adapter class calls the corresponding playVlc(fileName) based on the fileName. And playMp4 (fileName); Method, the next step is to implement the real method;

The illustration

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

We also have another interface AdvancedMediaPlayer and an entity class that implements the AdvancedMediaPlayer interface. This class can play VLC and MP4 files.

We want AudioPlayer to play audio files in other formats. To do this, we need to create a MediaAdapter class that implements the MediaPlayer interface and use the AdvancedMediaPlayer object to play the desired format.

AudioPlayerUsing adapter classesMediaAdapterPass the desired type of audio without knowing the actual class that can play audio in the desired format.AdapterPatternDemoClass USESAudioPlayerClass to play various formats.