Adapter Pattern
Also Known As
adapter
wrapper pattern
object adapter
TL;DR
Converts the interface of a class into another interface clients expect, allowing incompatible interfaces to work together.
Explanation
The Adapter (Wrapper) pattern bridges the gap between an existing class with an incompatible interface and the interface expected by client code. It wraps the adaptee and implements the target interface, translating calls. This is essential when integrating third-party libraries or legacy code without modifying either. In PHP, adapting a payment gateway SDK to a standardised PaymentGatewayInterface, or wrapping a legacy Logger to a PSR-3 LoggerInterface, are common use cases. Adapters also facilitate testability by wrapping external dependencies.
Diagram
flowchart LR
CLIENT[Client Code] -->|expects| TARGET[Target Interface<br/>send email]
TARGET -.->|implemented by| ADAPTER[SendGridAdapter]
ADAPTER -->|translates to| VENDOR[SendGrid SDK]
ADAPTER2[MailgunAdapter] -->|translates to| VENDOR2[Mailgun SDK]
CLIENT -.->|can swap| ADAPTER2
INFO[Client never changes<br/>only swap the adapter]
style CLIENT fill:#1f6feb,color:#fff
style ADAPTER fill:#238636,color:#fff
style ADAPTER2 fill:#238636,color:#fff
Common Misconception
✗ Adapter and Facade patterns are interchangeable. Facade simplifies a complex subsystem behind a single interface. Adapter makes an incompatible interface compatible with what a client expects — different problems, different solutions.
Why It Matters
The Adapter pattern wraps an incompatible interface to match an expected one — enabling integration of third-party code or legacy systems without modifying either side.
Common Mistakes
- Adapters that transform data as well as interface — separate the data mapping from the interface adaptation.
- Not programming to the target interface — the adapter is only useful if callers depend on the interface, not the adapter.
- Creating an adapter for every third-party class rather than a single adapter for the library's entry point.
- Adapters that leak the underlying library's exceptions — wrap them in domain exceptions.
Avoid When
- The interface mismatch is trivial — a one-line wrapper does not need a full adapter class.
- You control both interfaces and can change them — adapt the source instead of wrapping it.
- Overusing adapters hides poor API design that should be fixed at the source.
When To Use
- Integrating a third-party library whose interface does not match your domain's expectations.
- Making legacy code work with a new interface without modifying the legacy code.
- Enabling multiple implementations behind a single interface for swappability.
- Wrapping external APIs so your domain is insulated from their changes.
Code Examples
✗ Vulnerable
// Direct dependency on third-party Stripe library everywhere:
class PaymentService {
public function charge(float $amount): void {
\Stripe\Charge::create(['amount' => $amount * 100, 'currency' => 'usd']);
// Stripe leak throughout codebase — impossible to swap
}
}
// Better: StripePaymentAdapter implements PaymentGatewayInterface
✓ Fixed
// Your app expects this interface
interface Logger {
public function log(string $level, string $message): void;
}
// Third-party library uses a different API
class MonologAdapter implements Logger {
public function __construct(private \Monolog\Logger $monolog) {}
public function log(string $level, string $message): void {
$this->monolog->$level($message); // adapts your interface to Monolog's
}
}
// Your code depends on Logger — not Monolog directly
$logger = new MonologAdapter(new \Monolog\Logger('app'));
$service = new OrderService($logger);
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
25 Mar 2026
Views
44
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Amazonbot 17
Perplexity 8
ChatGPT 5
Google 5
Unknown AI 3
Ahrefs 2
Also referenced
How they use it
crawler 40
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Medium
⚡ Quick Fix
When integrating a third-party library that doesn't match your domain interface, create an adapter class that wraps the library and implements your interface
📦 Applies To
PHP 5.0+
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
Third-party class used directly in domain code without wrapping adapter; vendor class name imported in business logic
Auto-detectable:
✗ No
phpstan
deptrac
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: Class
Tests: Update