The Adapter Design Pattern is a structural design pattern that allows objects with incompatible interfaces to work together. It's like a translator between two parties that do not speak the same language. In this article, we'll break down the Adapter Design Pattern into four actionable steps, using real-world scenarios and code examples to make the concepts clear and easy to understand.
Step 1: Designing the Target Interface
The first step is to design the target interface that clients expect to work with. This interface defines the methods that will be used by the client.
Example Scenario: Media Player Application
Imagine you have a media player application that supports different audio formats. The target interface might look something like this:
public interface MediaPlayer {
void play(String audioType, String fileName);
}
Step 2: Implementing the Interface with Adapter Classes
Next, we implement the target interface using adapter classes. These adapters will translate the requests from the target interface into a format that the adaptee (the existing class) can understand.
AdvancedMediaPlayer Interface and Implementations:
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
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);
}
}
Adapter Class:
public 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();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer.playVlc(fileName);
} else if(audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer.playMp4(fileName);
}
}
}
Step 3: Sending the Request from Client to Adapter Using Target Interface
The client will send the request to the adapter using the target interface. The adapter will then translate the request and forward it to the appropriate adaptee.
AudioPlayer Class:
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
// Built-in support to play mp3 music files
if(audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file. Name: " + fileName);
}
// MediaAdapter is providing support to play 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 4: Implementing the Main Program
Finally, we implement the main program to demonstrate how the adapter pattern works in practice.
Main Program:
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");
}
}
Conclusion
The Adapter Design Pattern is an essential tool in your system design toolkit, allowing you to integrate and utilize incompatible interfaces seamlessly. By following these four steps—designing the target interface, implementing adapter classes, sending requests via the target interface, and implementing the main program—you can effectively bridge the gap between disparate systems and components.
By mastering the Adapter Design Pattern, you can enhance the flexibility and interoperability of your software systems, ensuring that diverse components work together harmoniously. Happy coding!
Top comments (0)