> For the complete documentation index, see [llms.txt](https://al-mamun.gitbook.io/al-mamun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://al-mamun.gitbook.io/al-mamun/design-patterns/adapter-pattern.md).

# Adapter Pattern

## 🔌 Adapter Design Pattern in PHP/Laravel

The **Adapter Pattern** is a structural design pattern that allows two incompatible interfaces to work together.

👉 It acts like a **translator** between your application and an external or legacy system.

***

## 🧠 Real-Life Analogy

Think about a **mobile charger adapter**.

* Your laptop charger uses one port
* Your wall socket uses another port
* Adapter converts them so they can work together

Software Adapter Pattern works the same way.

***

## ✅ When to Use Adapter Pattern

Use Adapter when:

* Integrating third-party APIs
* Migrating old systems
* Using multiple payment gateways
* Standardizing different services
* Wrapping legacy code

***

## 🏗️ Structure of Adapter Pattern

```
Client
   ↓
Target Interface
   ↓
Adapter
   ↓
Adaptee (Existing Class)
```

***

## Example 1: Payment Gateway Integration

### 🧠 Problem

Different payment gateways use different method names.

***

### Without Adapter ❌

{% code overflow="wrap" %}

```php
class Stripe {
    public function makePayment($amount) {
        return "Stripe Payment: $amount";
    }
}

class Paypal {
    public function payNow($amount) {
        return "Paypal Payment: $amount";
    }
}
```

{% endcode %}

Your application now needs:

```
$stripe->makePayment(100);
$paypal->payNow(100);
```

❌ Inconsistent API\
❌ Hard to maintain

***

## ✅ With Adapter Pattern

### Step 1: Create Standard Interface

```
interface PaymentGateway {
    public function pay($amount);
}
```

***

### Step 2: Existing Classes (Adaptees)

```
class Stripe {
    public function makePayment($amount) {
        return "Stripe Payment: $amount";
    }
}

class Paypal {
    public function payNow($amount) {
        return "Paypal Payment: $amount";
    }
}
```

***

### Step 3: Create Adapters

```
class StripeAdapter implements PaymentGateway {

    protected $stripe;

    public function __construct(Stripe $stripe) {
        $this->stripe = $stripe;
    }

    public function pay($amount) {
        return $this->stripe->makePayment($amount);
    }
}
```

```
class PaypalAdapter implements PaymentGateway {

    protected $paypal;

    public function __construct(Paypal $paypal) {
        $this->paypal = $paypal;
    }

    public function pay($amount) {
        return $this->paypal->payNow($amount);
    }
}
```

***

### Step 4: Usage

```
function processPayment(PaymentGateway $gateway, $amount) {
    echo $gateway->pay($amount);
}

processPayment(new StripeAdapter(new Stripe()), 500);

processPayment(new PaypalAdapter(new Paypal()), 1000);
```

***

## ✅ Benefits

* Standardized API
* Easy to switch gateways
* Clean architecture
* Open/Closed Principle supported

***

## Example 2: Laravel Notification Adapter

### 🧠 Scenario

You want to support:

* SMS
* Email
* WhatsApp

But all providers have different APIs.

***

### Step 1: Common Interface

```
interface NotificationInterface {
    public function send($to, $message);
}
```

***

### Step 2: Third Party Services

```
class TwilioService {
    public function sendSMS($number, $text) {
        return "SMS Sent";
    }
}
```

```
class MailchimpService {
    public function sendEmail($email, $content) {
        return "Email Sent";
    }
}
```

***

### Step 3: Adapters

```
class SMSAdapter implements NotificationInterface {

    protected $sms;

    public function __construct(TwilioService $sms) {
        $this->sms = $sms;
    }

    public function send($to, $message) {
        return $this->sms->sendSMS($to, $message);
    }
}
```

```
class EmailAdapter implements NotificationInterface {

    protected $mail;

    public function __construct(MailchimpService $mail) {
        $this->mail = $mail;
    }

    public function send($to, $message) {
        return $this->mail->sendEmail($to, $message);
    }
}
```

***

### Usage

```
$notification = new SMSAdapter(new TwilioService());

echo $notification->send('017XXXXXXXX', 'Hello User');
```

***

## Example 3: Legacy System Adapter

### 🧠 Scenario

Old ERP function:

```
class OldERPSystem {
    public function getCustomerData() {
        return ['name' => 'Sabuj'];
    }
}
```

New application expects:

```
interface CustomerService {
    public function getCustomer();
}
```

***

### Adapter

```
class ERPAdapter implements CustomerService {

    protected $erp;

    public function __construct(OldERPSystem $erp) {
        $this->erp = $erp;
    }

    public function getCustomer() {
        return $this->erp->getCustomerData();
    }
}
```

***

## Example 4: File Storage Adapter (Laravel-like)

### 🧠 Scenario

Different storage providers:

* Local
* AWS S3
* FTP

***

### Interface

```
interface StorageInterface {
    public function upload($file);
}
```

***

### Adaptees

```
class AwsS3 {
    public function putObject($file) {
        return "Uploaded to S3";
    }
}
```

```
class FTPStorage {
    public function sendFile($file) {
        return "Uploaded to FTP";
    }
}
```

***

### Adapters

```
class S3Adapter implements StorageInterface {

    protected $s3;

    public function __construct(AwsS3 $s3) {
        $this->s3 = $s3;
    }

    public function upload($file) {
        return $this->s3->putObject($file);
    }
}
```

```
class FTPAdapter implements StorageInterface {

    protected $ftp;

    public function __construct(FTPStorage $ftp) {
        $this->ftp = $ftp;
    }

    public function upload($file) {
        return $this->ftp->sendFile($file);
    }
}
```

***

## 🔥 Laravel Real Example

Laravel itself uses Adapter Pattern internally.

Example:

```
Cache::store('redis');
Cache::store('file');
Cache::store('database');
```

Different cache drivers → same interface.

Also:

* Database drivers
* Queue drivers
* Mail drivers
* Filesystem drivers

All use Adapter-like architecture.

***

## 📊 Advantages

| Advantage      | Description                                  |
| -------------- | -------------------------------------------- |
| Reusability    | Reuse old code                               |
| Flexibility    | Swap services easily                         |
| Clean Code     | Standardized interface                       |
| Scalability    | Add new adapters without changing core logic |
| Loose Coupling | Client doesn't depend on concrete classes    |

***

## ⚠️ Disadvantages

| Issue        | Explanation                        |
| ------------ | ---------------------------------- |
| More Classes | Extra adapter classes              |
| Complexity   | Overengineering for small projects |

***

## 🎯 Best Use Cases in Your ERP/POS

#### Perfect places to use Adapter Pattern:

✅ Payment Gateway\
✅ SMS Gateway\
✅ Courier API\
✅ ERP Integration\
✅ Multiple Database Drivers\
✅ Report Exporters\
✅ Inventory Vendor APIs\
✅ Cloud Storage

***

## 🚀 Professional Laravel Folder Structure

```
app/
├── Contracts/
│   └── PaymentGateway.php
├── Services/
│   ├── Stripe/
│   │   ├── Stripe.php
│   │   └── StripeAdapter.php
│   ├── Paypal/
│   │   ├── Paypal.php
│   │   └── PaypalAdapter.php
```

***

## 🎯 Key Idea to Remember

> Adapter Pattern does NOT change existing code.\
> It WRAPS existing code and translates interfaces.
