📝 What You’ll Learn
- What the Adapter Pattern is
- Why it’s useful for integrating incompatible interfaces
- How to implement it in Java
- Real-world examples and analogies
- Pitfalls and best practices
🔍 What Is the Adapter Pattern?
The Adapter Pattern allows incompatible classes to work together by translating one interface into another.
Think of it like a power plug adapter — it connects two mismatched systems so they can communicate.
🔁 When to Use It
Use the Adapter Pattern when:
- You need to use an existing class but its interface doesn’t match what you need
- You want to integrate legacy code with a new system
- You’re building a reusable system that requires interface flexibility
🧱 Java Implementation
🧩 Scenario
You have a MediaPlayer interface that expects to play audio files, but a third-party AdvancedMediaPlayer supports different methods.
🎧 Interfaces and Classes
// Target interface
public interface MediaPlayer {
void play(String audioType, String fileName);
}
// Adaptee (incompatible class)
public class AdvancedMediaPlayer {
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
public void playVlc(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
}
🔌 Adapter Class
public class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedPlayer = new AdvancedMediaPlayer();
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")) {
advancedPlayer.playVlc(fileName);
} else if(audioType.equalsIgnoreCase("mp4")) {
advancedPlayer.playMp4(fileName);
} else {
System.out.println("Invalid format: " + audioType);
}
}
}
✅ Usage
public class AudioPlayer implements MediaPlayer {
private MediaAdapter adapter;
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
} else {
adapter = new MediaAdapter();
adapter.play(audioType, fileName);
}
}
}
AudioPlayer player = new AudioPlayer();
player.play("mp3", "song.mp3");
player.play("mp4", "video.mp4");
player.play("vlc", "movie.vlc");
🔌 Real-World Analogy
Imagine you’re traveling abroad. Your laptop plug doesn’t fit the socket — so you use a travel adapter to bridge the gap. Same device, compatible through conversion.
⚠️ Pitfalls to Avoid
- ❌ Creating overly complex adapters for very simple integrations
- ❌ Ignoring the performance cost of adapting at runtime
- ❌ Confusing it with the Decorator or Facade pattern
✅ Best Practices
- Keep adapter logic simple and focused
- Prefer composition over inheritance
- Use adapters for interface compatibility, not behavior changes
📘 Recap
- Adapter Pattern helps classes with incompatible interfaces work together
- It wraps one class in another to translate interfaces
- Very useful for integrating third-party or legacy systems
- Real-world analogy: plug adapters, USB dongles, language translators