What is the Adapter Pattern?
Learn the Adapter design pattern — object vs class adapters, legacy integration — with a Java example and interview questions.
Expected Interview Answer
The Adapter pattern is a structural design pattern that converts the interface of an existing class into another interface a client expects, letting otherwise incompatible classes work together without modifying either one.
An adapter wraps an incompatible object (the adaptee) and implements the target interface the client already depends on, translating calls between the two on the fly. This is especially valuable when integrating third-party or legacy code whose interface cannot be changed, since the adapter isolates that mismatch in one place instead of scattering conversion logic throughout the codebase. Adapters can be implemented via composition (object adapter, wrapping the adaptee) or, in languages with multiple inheritance, via inheritance (class adapter); composition is generally preferred for flexibility.
- Reuses existing or third-party code without modifying it
- Isolates interface-conversion logic in a single, testable place
- Lets clients depend only on the interface they expect
- Enables swapping adaptees without touching client code
AI Mentor Explanation
A cricket commentator broadcasting to an international audience uses a translator who converts cricket-specific terminology into concepts the audience already understands, without changing how the game itself is played. The translator sits between the game and the audience, converting one vocabulary into another compatible one. That is the Adapter pattern: a wrapper converts an incompatible interface into the one the client actually expects, without modifying the original.
Step-by-Step Explanation
Step 1
Identify the target interface
Determine the interface the client code already expects to work with.
Step 2
Identify the incompatible adaptee
Find the existing class whose interface does not match what the client needs.
Step 3
Create the adapter class
Implement the target interface, wrapping (or extending) the adaptee internally.
Step 4
Translate calls
Each target-interface method delegates to the adaptee, converting parameters or results as needed.
What Interviewer Expects
- A clear real-world example (e.g. legacy or third-party integration)
- Distinction between object adapter (composition) and class adapter (inheritance)
- Understanding that neither the client nor the adaptee is modified
- Awareness of when Adapter is preferred over rewriting the adaptee
Common Mistakes
- Confusing Adapter with Decorator (Decorator adds behavior, Adapter changes interface)
- Modifying the adaptee's source instead of wrapping it
- Overusing adapters instead of fixing a genuinely broken interface design
- Not considering composition-based adapters as the more flexible default
Best Answer (HR Friendly)
“The Adapter pattern lets two incompatible interfaces work together by wrapping one of them and translating its calls into the format the other side expects. It is especially useful for integrating legacy or third-party code you can’t or shouldn’t modify directly.”
Code Example
// Target interface the client expects
interface MediaPlayer {
void play(String fileName);
}
// Incompatible legacy adaptee
class LegacyAudioSystem {
void playLegacyFormat(String file) {
System.out.println("Playing via legacy system: " + file);
}
}
// Adapter converts LegacyAudioSystem into MediaPlayer
class LegacyAudioAdapter implements MediaPlayer {
private final LegacyAudioSystem legacy = new LegacyAudioSystem();
@Override
public void play(String fileName) {
legacy.playLegacyFormat(fileName); // translate the call
}
}
MediaPlayer player = new LegacyAudioAdapter();
player.play("song.mp3"); // client only knows the MediaPlayer interfaceFollow-up Questions
- What is the difference between the Adapter pattern and the Decorator pattern?
- When would you use a class adapter instead of an object adapter?
- How does the Adapter pattern support the Open/Closed Principle?
- Can you give a real-world example from a library or framework you have used?
MCQ Practice
1. The primary purpose of the Adapter pattern is to?
Adapter translates between two incompatible interfaces without modifying either original class.
2. An object adapter achieves the interface conversion primarily through?
Object adapters hold a reference to the adaptee and delegate calls to it, favoring composition.
3. Adapter differs from Facade mainly because?
Adapter is about interface compatibility between two specific types; Facade simplifies access to a broader subsystem.
Flash Cards
Adapter pattern in one line? — Converts an incompatible interface into the one a client expects, via a wrapper.
Object adapter vs class adapter? — Object adapter uses composition; class adapter uses inheritance.
What is never modified? — Neither the client's expected interface nor the adaptee's original code.
Classic use case? — Integrating legacy or third-party code with an incompatible interface.