Adapter Design Pattern
It ‘s a structural design pattern that allows objects with incompatible interfaces to work together. Think of it as a translator between two systems.
Get shubham mishra’s stories in your inbox
Join Medium for free to get updates from this writer.
Much like how a power plug adapter lets you use a US device in a European socket, the Adapter Pattern allows your class to “plug into” another system that it wasn’t designed to work with.
🧠 When Should You Use It?
- When you’re integrating legacy code that doesn’t match the current interface.
- When you want to reuse a class but its interface doesn’t match your application.
- When working with third-party APIs or library code that you can’t change.
🛠 Real-World Analogy
Imagine a card reader that lets you insert a memory card into your laptop. The memory card can’t plug in directly, but the card reader adapts its interface to one the laptop understands — USB.
📦 Types of Adapters
1. Object Adapter (uses composition)
Most commonly used in Java and modern OO languages.
2. Class Adapter (uses inheritance)
Less common, due to single inheritance restrictions in many languages.
🧑💻 Let’s Use a Simple Code Example
🎯 Goal: We have an old video player that plays .mp4 files. But now we want to build a system where users just call .play("mp4", "video.mp4"), and it should work with the old player.
🔧 Step-by-Step Code
1. Target Interface — what our new system expects
public interface MediaPlayer {
void play(String audioType, String fileName);
}
//➡️ This is what our client code will call. It doesn’t care how files are played, it just says: “Play this file.”2. Existing Code — the “Legacy” class
public class LegacyPlayer {
public void playMp4(String fileName) {
System.out.println("Playing mp4 file: " + fileName);
}
}
//➡️ This is old code or third-party library. It can play .mp4, but only with a different method name.3. Adapter — makes the old code fit the new interface
public class MediaAdapter implements MediaPlayer {
private LegacyPlayer legacyPlayer = new LegacyPlayer();
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp4")) {
legacyPlayer.playMp4(fileName); // call the old method
} else {
System.out.println("Unsupported format: " + audioType);
}
}
}
//This class adapts the AdvancedMediaPlayer to work with the MediaPlayer interface.4. Client Code — uses only the new interface
public class AudioPlayer implements MediaPlayer{
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
mediaAdapter = new MediaAdapter();
mediaAdapter.play(audioType, fileName);
}
}
//➡️ The client calls play("mp4", "song.mp4") and doesn’t know or care how it's handled inside.✅ Output When Run
AudioPlayer player = new AudioPlayer();
player.play("mp4", "song.mp4");🖨 Output:
Playing mp4 file: song.mp4Benefits
- Promotes code reusability.
- Helps integrate legacy or third-party code.
- Follows the Open/Closed Principle (from SOLID).
Drawbacks
- Can add extra layers of complexity.
- Might make system harder to debug if overused.
📚 GitHub Repository for Reference:
👉 https://github.com/iamshubhammishra/java-design-patterns/tree/main/adapter







