00:00

Adapter Design Pattern

The Adapter Design Pattern is a structural design pattern used in object-oriented programming. It helps two incompatible interfaces work together without changing their existing code.

In simple words, an adapter acts like a bridge between two different systems. Just like a mobile charger adapter allows you to charge your phone using a different socket, this pattern allows classes with different interfaces to communicate.

Why Do We Need the Adapter Pattern?

Many times, we work with:

  • Legacy code that we cannot modify
  • Third-party libraries with fixed interfaces
  • New systems that must work with old systems

Instead of changing existing code (which may be risky or impossible), we create an adapter that converts one interface into another.

Real-Life Example

Imagine you have a music player that supports only MP3 files, but now you want to play MP4 or VLC files.

Instead of changing the music player itself, you create an adapter that converts MP4 or VLC files into a format the player understands.

Adapter Pattern Example in Java

Step 1: Create the Target Interface

This is the interface expected by the client.


interface MediaPlayer {
    void play(String audioType, String fileName);
}

Step 2: Create an Existing (Incompatible) Interface

This interface already exists and cannot be changed.


interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

Step 3: Create Concrete Implementations


class VlcPlayer implements AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        System.out.println("Playing VLC file: " + fileName);
    }

    public void playMp4(String fileName) {
        // Not supported
    }
}

class Mp4Player implements AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        // Not supported
    }

    public void playMp4(String fileName) {
        System.out.println("Playing MP4 file: " + fileName);
    }
}

Step 4: Create the Adapter Class

This class adapts AdvancedMediaPlayer to MediaPlayer.


class MediaAdapter implements MediaPlayer {

    AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer = new Mp4Player();
        }
    }

    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer.playMp4(fileName);
        }
    }
}

Step 5: Create the Client Class


class AudioPlayer implements MediaPlayer {

    MediaAdapter mediaAdapter;

    public void play(String audioType, String fileName) {

        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing MP3 file: " + fileName);
        } 
        else if (audioType.equalsIgnoreCase("vlc") 
              || audioType.equalsIgnoreCase("mp4")) {

            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } 
        else {
            System.out.println("Invalid media type: " + audioType);
        }
    }
}

Step 6: Test the Adapter Pattern


public class AdapterPatternDemo {
    public static void main(String[] args) {

        AudioPlayer audioPlayer = new AudioPlayer();

        audioPlayer.play("mp3", "song.mp3");
        audioPlayer.play("mp4", "video.mp4");
        audioPlayer.play("vlc", "movie.vlc");
        audioPlayer.play("avi", "file.avi");
    }
}

Output

Playing MP3 file: song.mp3
Playing MP4 file: video.mp4
Playing VLC file: movie.vlc
Invalid media type: avi

Key Advantages of Adapter Design Pattern

  • Allows incompatible interfaces to work together
  • Improves code reusability
  • Follows Open/Closed Principle
  • Avoids modifying existing or legacy code

When Should You Use Adapter Pattern?

  • When existing classes cannot work with new interfaces
  • When using third-party libraries with different APIs
  • When migrating old systems to new systems

Conclusion

The Adapter Design Pattern is a simple yet powerful solution to make incompatible systems work together. By using an adapter, you keep your code clean, flexible, and easy to maintain.

It is widely used in real-world Java applications, frameworks, and APIs.