Skip to main content
computer-science engineering-and-technology linguistics

Adapter

Description

When a client and a service want to talk but speak different interface dialects, an adapter sits between them and translates. The adapter’s surface on the client-facing side matches the client’s expectations; its consumption side matches the service’s native shape; and the body of the adapter is the translation logic that bridges the gap. The mismatch can be at any level — type signature, protocol, encoding, units, calling convention, identifier scheme. What unifies the cases is the structural three-role architecture (client / adapter / service) plus an explicit naming of the mismatch the adapter absorbs. Adapters are the standard move when you can’t change either side (the service is third-party; the client is legacy code). They’re the don’t break the seam; live on it solution.

Triggers

User-initiated: User says “I want X to work with Y but they don’t match,” or proposes a wrapper / shim / translation layer. Vocabulary cues: “adapter,” “shim,” “wrapper,” “translates between,” “bridges,” “converter,” “I can’t change either side.” Agent-initiated: Agent notices two components with structurally-compatible but interface-incompatible shapes — same data, different schema; same operation, different signature. Candidate inference: “introduce an adapter at the seam; explicitly name the mismatch the adapter absorbs.” Situation-shape signals: Third-party API call that can’t quite hand its result to the local code. Two libraries that should compose but don’t. Legacy system + new system both speaking some flavor of the same data. Cross-language FFI boundaries.

Exclusions

  • Both sides are under your control — when you can change either side, refactoring to a shared interface is usually cleaner than introducing an adapter; the adapter pattern is mostly for the can’t-change-either-side constraint.
  • The mismatch is semantic, not syntactic — if the two systems disagree about what the data means (not just how it’s shaped), an adapter that just translates shape will silently propagate the semantic mismatch; you need an explicit reconciliation policy, not just an adapter.
  • The mismatch is structurally large — if the adapter has to reconstitute significant missing information, it’s no longer an adapter; it’s a translator with synthesis, and the structural primitive shifts.

Structure

Internal structure of adapter: a table of its component slots and the concepts that fill them.

Relationships

Relationship neighborhood of adapter: a graph of the concepts it connects to and the concepts it is a part of.
  • seam — adapters live at seams; choosing where to put the adapter is choosing which seam to absorb the mismatch at.
  • surface — the adapter has two surfaces — the client-facing one and the service-facing one — and the translation work is the body between them.
  • multi-channel-ingest — multi-channel ingestion is typically N adapters (one per channel) feeding a unified internal representation.
  • leaky-abstraction — adapters are abstractions and so leak; the leak is usually the seam’s residual shape that didn’t quite translate (e.g., ORM cache invalidation, dongle power-draw mismatches).
  • proxy — proxy is the same-interface sibling; adapter is the different-interface case.

Examples

Adapter in OOP · computer-science

ListAdapter wrapping an array to make it implement a List interface; the most literal GoF instance.

Power plug adapters · engineering-and-technology

US-shape plugs to EU outlets; the body of the adapter is just pin geometry translation.
in domain-driven design, the ACL is explicitly an adapter that protects a clean domain model from a messy legacy system’s shape.
Eric Evans’s Domain-Driven Design (2003) introduces the anti-corruption layer (ACL) as the recommended pattern when one bounded context must integrate with another whose model is misaligned — typically a legacy system or third-party service whose vocabulary, invariants, or coarse-grain shape would pollute the new system if imported directly. The ACL is an adapter scaled up to architectural significance: it translates not just method signatures but concepts, preventing the foreign model’s terminology and rules from leaking across the boundary.Inference: The ACL is the adapter pattern with a sharpened scope condition — when the mismatch is large enough that an unmediated bridge would let one model’s vocabulary corrupt the other, the adapter becomes load-bearing for the integrity of the receiving model, not just a syntactic convenience.
A travel plug adapter is the physical archetype of the adapter pattern. Wall sockets diverge by region — North America standardizes on NEMA Type A/B, continental Europe on the CEE 7 “Schuko” family, the UK on BS 1363 Type G — and a device built for one cannot be inserted into another. The adapter sits exactly at this seam: it exposes the socket-side shape the foreign outlet expects on one face and the device-side shape the plug expects on the other, re-routing pin geometry between the two. The client here is the appliance’s plug, the service is the wall outlet, and the mismatch it absorbs is purely mechanical connector geometry.The crucial discipline is the boundary of what the adapter does not translate: it carries the raw voltage and frequency through unchanged. Plug a single-voltage 120V device into a 230V outlet through an adapter and you destroy it — because the mismatch the adapter absorbed was syntactic (pin shape), while the dangerous mismatch was semantic (voltage). That the IEC’s attempt at a single universal connector, IEC 60906-1, has gone almost entirely unadopted (only South Africa and a few others) is itself instructive: when neither side can be made to change, the world routes around the incompatibility with adapters rather than converging on a shared interface.Inference: a clean adapter translates shape and is honest about not translating meaning; an adapter that silently passes through a semantic mismatch (voltage, units, encoding, currency) looks like it’s bridging the gap but is actually propagating the failure downstream.
The USB-C dongle is a richer instance of the adapter than the passive travel plug, because it bridges protocol as well as physical shape. A USB-C port can carry several different signals over the same connector, and a dongle exposes a legacy interface a host or peripheral still expects — HDMI, VGA, USB-A, Ethernet — while internally translating to the USB-C physical and protocol layer. The host believes it is talking to a plain HDMI port; a bridge chip inside the dongle negotiates DisplayPort Alt Mode over the connector’s configuration channel and reshapes the result into the signal the monitor understands. The client is the legacy peripheral, the service is the USB-C host, the adapter is the dongle, and the mismatch it spans covers both connector geometry and the wire protocol.That physical adapters of this kind predate the object-oriented “Adapter” coinage by a century — power plugs, then dongles — is the point: the structure is not a software invention. It is the same three-role shape (client expects interface A, provider offers interface B, an intermediary at the seam translates A↔B) recurring wherever two independently-evolved standards must interoperate without either being rebuilt. The cross-domain reach is what earns adapter a place in a catalog of structural primitives rather than a place in a list of programming idioms.
GoF Adapter, catalogued among the seven structural patterns in chapter 4 of Design Patterns, is the canonical named primitive for the impedance-matching intermediary. The book distinguishes object adapters (which compose with the adaptee via delegation) from class adapters (which inherit from the adaptee), but both share the same structural three-role architecture — client expects one interface, adapter exposes that interface, service offers a different one — that recurs far beyond OOP.Once you have the name, the adapter shape shows up everywhere: USB-C dongles bridging physical connector standards, ORMs translating between row-oriented SQL and object graphs, language interpreters bridging programming-language ABIs, and protocol bridges translating between message formats. The book’s contribution to engineering practice was making the shape transmissible.
The 1994 Design Patterns book by Gamma, Helm, Johnson, and Vlissides catalogued Adapter as one of seven structural patterns (alongside Bridge, Composite, Decorator, Facade, Flyweight, and Proxy). Their canonical illustration shows a client expecting a Target interface confronted with an existing Adaptee whose method names and parameters don’t match; the Adapter class implements Target and delegates to Adaptee, performing whatever name/argument translation is required.The book’s contribution wasn’t the move itself — wrapping mismatched interfaces is older than OOP — but the naming: pinning down a portable, transmissible label for a recurring three-role architecture. Once the name existed, engineers could point at an instance and say “that’s an Adapter,” and the conversation about whether to refactor vs. wrap could happen in shared vocabulary.
Hyrum’s Law states: “With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.” Articulated by Hyrum Wright at Google (and named by his colleague Titus Winters in Software Engineering at Google), it is the observation that scale converts every incidental behavior — error-message text, iteration order, latency, the exact shape of a translation — into a de facto part of the interface.Applied to the adapter pattern, this names a failure mode of the adapter itself. An adapter is introduced to absorb the mismatch between a client and a service, and its job is in principle invisible: it should be a thin, swappable translation layer. But once it exists and acquires enough callers, its observable translation behavior — not just the contract it documents — gets depended upon. Quirks the adapter never promised (how it rounds, how it orders, how it renders a null) become load-bearing for someone downstream. The adapter you meant to keep replaceable has, by Hyrum’s Law, hardened into an interface of its own.Inference: treat an adapter’s full observable behavior, not its documented contract, as the real interface once it has many users. Either keep it genuinely thin and few-callered, or accept that “just swap the adapter” is no longer a free move.
human-language adapter; absorbs grammar, idiom, and cultural-reference mismatches.
application speaks objects; database speaks SQL rows; the ORM is the (famously leaky) adapter.
gRPC ↔ REST gateways; MQTT ↔ HTTP shims; format converters (CSV ↔ JSON).
laptop expects USB-C; peripheral has USB-A; the dongle is the adapter.