Structural Patternshigh

Adapter Pattern

Convert the interface of a class into another interface that clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Memory anchor

Adapter = a travel plug converter. Your US laptop charger (old interface) meets a European wall socket (expected interface). The adapter doesn't change the voltage — it just makes the prongs fit.

Expected depth

Two forms: class adapter (extends the adaptee — requires multiple inheritance, common in C++) and object adapter (wraps the adaptee via composition — preferred in Java/Go). Use cases: wrapping a third-party library behind your own interface, integrating legacy systems, making new code conform to an existing interface contract. In a payment system: your domain defines a PaymentGateway interface; a StripeAdapter wraps the Stripe SDK and translates Stripe's API into your interface.

Deep — senior internals

Object adapter via composition is preferred because it does not bind you to the adaptee's class hierarchy, allows adapting classes you cannot subclass (final), and allows adapting multiple adaptees in one adapter. Adapter differs from Facade: Adapter makes one interface look like another (one-to-one mapping); Facade simplifies a complex subsystem behind a single unified interface (many-to-one). Adapter differs from Proxy: Adapter changes the interface; Proxy keeps the interface identical and controls access. Adapter is the pattern of choice for the Anti-Corruption Layer in Domain-Driven Design — it translates between bounded contexts so your domain model is not polluted by external nomenclature.

🎤Interview-ready answer

Adapter is my go-to for third-party library integration. I define a PaymentGateway interface in my domain. Then I write a StripeAdapter that holds a StripeClient reference and implements PaymentGateway — translating my domain's charge(Money amount) into Stripe's createCharge() call. The domain never imports the Stripe SDK. If I need to switch to Braintree, I write a BraintreeAdapter and change one DI binding. I always use object adapter (composition) over class adapter (inheritance) — it avoids the adaptee's class hierarchy entirely.

Common trap

Adapter does not add behaviour — it translates. If you find yourself adding logic in the adapter beyond translation, you may have misidentified the pattern. That logic belongs in a service or decorator.

Related concepts