Adapter
The Adapter pattern is the travel plug of code — a small piece that sits between two things that do not fit and lets them work together anyway. Your laptop charger does not fit a foreign wall socket, so you drop in a plug adapter and it just works. Neither the charger nor the wall had to change; the adapter did the translating in the middle. Here is the Adapter pattern explained simply — the everyday idea, then the moments it saves you from rewriting code you would rather leave alone.
What is it
An Adapter is a small in-between piece that makes two mismatched things fit. One side offers what it has in one shape; the other side expects a different shape. The adapter takes what the first side gives and re-presents it in the form the second side wants. Picture a travel plug adapter. Your two-pin charger on one side, the three-hole foreign socket on the other, and the adapter bridging the gap. Neither end changes. The adapter quietly does the fitting.
How it works
The adapter wraps the thing that does not fit and puts a new face on it — the face the other side already knows how to talk to. When your code asks the adapter for something, the adapter turns around, asks the wrapped thing in its own language, takes the answer, and reshapes it into what your code expected. Your code never learns that a translation happened. The wrapped thing never learns it is being translated. Only the adapter sits in the middle knowing both sides, exactly like the plug adapter that understands both the two-pin charger and the three-hole wall.
When to use
Reach for an Adapter when you want to use something that almost fits but not quite. A shiny new library whose method names do not match what your old code already calls. A payment service that hands back data in a different shape than the rest of your app expects. Two parts, each fine on its own, that simply speak different dialects. Rather than rewrite either one, you slip an adapter between them and let it translate — the cheap fix that leaves both sides untouched. It shows up everywhere real apps meet the outside world: wrapping a maps SDK, a payment provider, or an old data feed so the rest of your code keeps speaking its own clean language.
Watch out for
The honest catch is that an adapter hides a mismatch; it does not fix a bad design. If two parts keep needing adapters to talk, that is a hint the design underneath is fighting itself, and a real cleanup would serve you better than another translator. Stacking adapters on adapters turns your code into a hall of mirrors — hard to follow which layer speaks what. Every adapter is also one more hop to trace when you are hunting a bug. Use it to bridge an honest gap, not to paper over a mess you should tidy. When your goal is to hide a whole tangled system behind one simple front door rather than translate one mismatched piece, the Facade pattern fits better.
In real code
Wrapping an old payment gateway so new code can call it the standard way.
Pseudocodeinterface Target: # the shape your code expects
pay(amount)
class OldGateway: # the mismatched thing
sendMoney(cents)
class GatewayAdapter implements Target:
old = new OldGateway()
pay(amount):
old.sendMoney(amount * 100) # translate, then hand off
Neither your code nor the old gateway had to change.
Javainterface Target { // what your code calls
void pay(double amount);
}
class GatewayAdapter implements Target {
private final OldGateway old = new OldGateway();
public void pay(double amount) {
old.sendMoney((int)(amount * 100)); // dollars -> cents
}
}
Analogy
A travel plug adapter. Your charger has one kind of plug, the foreign wall has another, and the little adapter sits between them so they connect. Neither the charger nor the wall changes — the adapter does all the fitting.
Practice lessons
Lessons coming soon.