Adapter Pattern
Convert the interface of a class into another interface clients expect.
Intent & Objective
Allow objects with incompatible interfaces to collaborate by providing a wrapper that translates calls from one interface into calls to another.
"When you visit another country, your domestic device charger cannot physically fit the foreign wall socket. The adapter bridges electrical pins and voltages so incompatible hardware works together."
"Bridges two diplomats who do not speak a common language, translating phrases in real time without forcing either speaker to learn a new language."
"Adapts commands to control diverse TV, audio soundbar, and cable box brands through one consistent set of buttons."
The Problem
You need to integrate a third-party analytics library or legacy system whose method names, parameter signatures, and return types conflict with your domain model.
The Solution
Create an Adapter class that implements your standard client interface and wraps the incompatible adaptee object, delegating and transforming method calls.
Key Participants & Architectural Roles
Code Samples (Traditional OOP vs Functional Programming)
Available in C++, Python, and JavaParadigm Contrast: Traditional OOP vs Functional / Data-Oriented
In OOP, Adapter creates an adapter wrapper class inheriting an interface. In Functional Programming, an Adapter is simply a pure function mapping or currying: `f(x) = g(transform(x))` or function composition `(g . f)`.
Advantages
- ✓ Single Responsibility Principle: separates interface/data conversion from core business logic
- ✓ Open/Closed Principle: introduces new adapters without breaking existing client code
- ✓ Reuses existing, battle-tested legacy libraries
Trade-offs
- ✗ Increases overall code complexity by introducing new interfaces and adapter classes
When to Apply
- → When you want to use some existing class, but its interface isn’t compatible with the rest of your code
- → When you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass
When to Avoid
- ! When you have full control over both classes and can simply refactor them directly