← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Adapter Pattern

general PHP 5.0+ Intermediate

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);

Added 15 Mar 2026
Edited 25 Mar 2026
Views 44
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 2 pings M 0 pings T 1 ping W 1 ping T 1 ping F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 1 ping T
No pings yesterday
Amazonbot 17 Perplexity 8 ChatGPT 5 Google 5 Unknown AI 3 Ahrefs 2
crawler 40
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

✓ schema.org compliant