Adapter
Make incompatible interfaces work together
Overview
The Adapter pattern allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces by wrapping one interface to make it compatible with another.
Think of it like a power adapter that allows a US plug to work in a European socket.
Key Concepts
Converts one interface to another
Makes incompatible interfaces work together
Object Adapter (composition) vs Class Adapter (inheritance)
Wraps existing class with new interface
Also called Wrapper pattern
Code Example
1// Target interface - what client expects
2interface MediaPlayer {
3 void play(String filename);
4}
5
6// Adaptee - existing class with incompatible interface
7class AdvancedVideoPlayer {
8 public void playMp4(String filename) {
9 System.out.println("Playing MP4: " + filename);
10 }
11
12 public void playVlc(String filename) {
13 System.out.println("Playing VLC: " + filename);
14 }
15}
16
17// Another Adaptee
18class ThirdPartyAudioPlayer {
19 public void playAudio(String file, String format) {
20 System.out.println("Playing " + format + " audio: " + file);
21 }
22}
23
24// Adapter - makes AdvancedVideoPlayer compatible with MediaPlayer
25class VideoAdapter implements MediaPlayer {
26 private AdvancedVideoPlayer videoPlayer;
27
28 public VideoAdapter() {
29 this.videoPlayer = new AdvancedVideoPlayer();
30 }
31
32 @Override
33 public void play(String filename) {
34 if (filename.endsWith(".mp4")) {
35 videoPlayer.playMp4(filename);
36 } else if (filename.endsWith(".vlc")) {
37 videoPlayer.playVlc(filename);
38 }
39 }
40}
41
42// Adapter for third-party audio player
43class AudioAdapter implements MediaPlayer {
44 private ThirdPartyAudioPlayer audioPlayer;
45
46 public AudioAdapter() {
47 this.audioPlayer = new ThirdPartyAudioPlayer();
48 }
49
50 @Override
51 public void play(String filename) {
52 String format = filename.substring(filename.lastIndexOf('.') + 1);
53 audioPlayer.playAudio(filename, format);
54 }
55}
56
57// Client
58class UniversalPlayer implements MediaPlayer {
59 private MediaPlayer mp3Player;
60 private VideoAdapter videoAdapter;
61 private AudioAdapter audioAdapter;
62
63 public UniversalPlayer() {
64 this.videoAdapter = new VideoAdapter();
65 this.audioAdapter = new AudioAdapter();
66 }
67
68 @Override
69 public void play(String filename) {
70 if (filename.endsWith(".mp3")) {
71 System.out.println("Playing MP3: " + filename);
72 } else if (filename.endsWith(".mp4") || filename.endsWith(".vlc")) {
73 videoAdapter.play(filename);
74 } else {
75 audioAdapter.play(filename);
76 }
77 }
78}
79
80// Usage
81public class Main {
82 public static void main(String[] args) {
83 MediaPlayer player = new UniversalPlayer();
84
85 player.play("song.mp3"); // Built-in
86 player.play("movie.mp4"); // Via VideoAdapter
87 player.play("clip.vlc"); // Via VideoAdapter
88 player.play("track.wav"); // Via AudioAdapter
89 }
90}VideoAdapter and AudioAdapter wrap incompatible players to implement the MediaPlayer interface.
When to Use
When you want to use an existing class with incompatible interface
Integrating third-party libraries
Working with legacy code
When you can't modify the original class
Real-World Example
- Power adapters (US to EU plugs)
- Java's Arrays.asList() adapts array to List
- InputStreamReader adapts InputStream to Reader
- Database adapters (JDBC drivers)
💡 Interview Tips
Explain the adapter analogy (power adapter)
Show object adapter (composition) approach
Discuss real-world examples in Java
Compare with Facade (simplifies vs adapts)
Know when to use adapter vs bridge