100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Adapter Pattern

BeginnerTechnique9.9K learners

The Adapter pattern is a structural design pattern that converts the interface of one class into another interface that clients expect, allowing otherwise incompatible classes to work together.

Definition

The Adapter pattern is a structural design pattern that converts the interface of one class into another interface that clients expect, allowing otherwise incompatible classes to work together.

Overview

The Adapter pattern, from the Gang of Four catalog, solves interface-incompatibility problems: when existing code expects to work with objects conforming to interface A, but you need to integrate a class that exposes a different interface B (often because it's a third-party library, legacy code, or a class you cannot modify), an adapter sits between them, implementing interface A and translating each call into the equivalent call(s) on the wrapped B object. This lets otherwise incompatible components collaborate without modifying either the client code or the adapted class. There are two classic implementation styles. The object adapter uses composition: the adapter holds a reference to an instance of the adaptee and implements the target interface by delegating to that instance, translating method signatures and data formats as needed. The class adapter uses multiple inheritance (in languages that support it, like C++) to inherit from both the target interface and the adaptee simultaneously. Object adapters are more common in modern practice because most mainstream languages (Java, C#, most of the Python/JS ecosystem) don't support multiple implementation inheritance, and composition is generally favored over inheritance for flexibility. Adapter is extremely common in integration code: wrapping a third-party payment gateway's SDK behind your application's internal `PaymentProvider` interface so you can swap providers later; wrapping a legacy system's API in a modern interface so new code doesn't need to know about the legacy format; or translating between data formats (e.g., converting a REST API's JSON response shape into the domain objects your application expects). It's also foundational to the broader practice of building anti-corruption layers in domain-driven design, where an adapter-like boundary layer protects a system's internal model from being polluted by an external system's model. Unlike Decorator, which preserves an object's interface while adding behavior, Adapter's defining purpose is changing the interface itself so two otherwise mismatched components can interoperate.

Key Concepts

  • Converts one interface into another interface that a client expects
  • Enables integration of otherwise-incompatible classes without modifying either side
  • Object adapter: uses composition, holding a reference to the wrapped adaptee
  • Class adapter: uses multiple inheritance (in languages that support it)
  • Commonly used to wrap third-party libraries behind an internal application interface
  • Central to 'anti-corruption layers' that isolate a system from external models
  • Distinct from Decorator, which preserves the interface rather than translating it
  • Facilitates swapping vendors/implementations without touching client code

Use Cases

Wrapping a third-party SDK (payments, cloud storage, auth) behind an internal interface
Integrating legacy systems with modern application code
Translating between different data formats or API response shapes
Making a class with an incompatible interface conform to a shared abstraction used elsewhere in the app
Building anti-corruption layers between microservices with differing domain models
Supporting multiple external providers interchangeably behind one interface

Frequently Asked Questions