Johnny Butler

June 30, 2026

The Adapter Pattern Is Commercial Leverage, Not Clean Code

The adapter pattern is one of the first design patterns every engineer and agent should understand — and every integration you’ve shipped, from Stripe to a maps API, is why. The bigger question now is whether your AI coding agent knows what it is, and when to reach for it.

Almost every external-provider dependency starts the same way: free credits, a generous tier, good docs, just enough API to ship. That is usually the right call. The mistake shows up later, two years on, that provider is wired through the whole codebase, the pricing has changed, the quotas bite, and switching off it has quietly become a project nobody wants to own.

That is the problem adapters help with: translating provider-specific APIs into an interface the rest of your application understands. If you later need fallback, routing, or provider selection, you may add strategy-shaped behaviour at the wiring layer. The important boundary is the same: stop letting external-provider decisions leak through the whole product. It is not clean-code decoration. It is commercial leverage. The Google Maps / OpenStreetMap case is the simple version: Google for coverage, OSM or OSRM where cost, routing, or overflow makes more sense. The point is not that every map-heavy product needs this on day one. It is that external-provider dependencies become business decisions far faster than teams expect.

Which is exactly where agentic coding gets interesting. Telling an AI agent to "use design patterns" is mostly a hope. It can name the adapter pattern. It can even generate something shaped like one. What it will not reliably do on its own is the judgement that actually matters: has this boundary burned us before, would an adapter be premature here, what behaviour must the tests protect at the provider boundary, and what trade-off still needs a human to make the call.

Show, don’t tell. I’ve attached a Ruby provider-boundary example I actually give an agent so it can see what good looks like here: adapters translating provider APIs into the shape the app expects, with the wiring kept outside the core calling code.

adapter-pattern-edited.png


That is the difference between design-pattern theatre and engineering discipline inside the delivery loop. The agent should not just hand back a pattern-shaped diff. It should show why the boundary was chosen, what behaviour held, what it verified, and where the judgement call still sits.

Naming a pattern is a hope. Proving it earned its place is an operating model.