creational
Adapter
Convert the interface of a class into another interface that clients expect.
You have code that expects one interface, and a class that offers a different one. Both work fine. They just do not fit.
This happens constantly with third-party libraries and old systems. You cannot edit the library, and rewriting your own code to match it would spread that library's shape through your whole project.
Adapter is a small class that sits between them. It implements the interface your code expects, and translates each call into whatever the other class actually needs.
A power plug adapter — your device expects round pins; the wall has flat pins. The adapter bridges the gap.
Key Concepts
1
The adapter implements the interface your code already uses, so your code needs no changes at all.
2
Inside, it holds a reference to the class it is adapting. Each method converts the arguments, calls the real method, and converts the result back.
3
All the awkwardness lives in this one small class. If you later replace the library, you rewrite the adapter and nothing else.
When to use it
- Integrating third-party libraries
- Reusing legacy code in a new system
- Making unrelated classes work together
Watch out for
- Prefer Object Adapter (composition) over Class Adapter (inheritance) for flexibility.
java
public class LegacyAnalytics {
public void trackEvent(String cat, String action, int val) { }
}
public interface Analytics {
void logEvent(String name, Map<String, Object> props);
}
public class AnalyticsAdapter implements Analytics {
private final LegacyAnalytics legacy;
public AnalyticsAdapter(LegacyAnalytics l) { this.legacy = l; }
public void logEvent(String name, Map<String, Object> props) {
String cat = (String) props.getOrDefault("category", "general");
int val = (int) props.getOrDefault("value", 0);
legacy.trackEvent(cat, name, val);
}
}