# Adapter — Design Patterns

Source: https://www.skillbyai.com/en/design-patterns/s-adapter

> Make an incompatible interface fit.

## Translating between interfaces

**Intent:** convert the interface of an existing class into the interface your code expects, so they can work together without changing either. Typical uses: wrapping a third-party SDK behind your own interface, integrating a legacy module, or supporting several vendors (two payment providers, two SMS services) through one interface. The adapter translates method names, argument shapes, units (cents versus decimal amounts) and errors. **Use it when** you integrate code you do not control. A useful side effect is an **anti-corruption layer**: vendor types stay inside the adapter instead of leaking across your codebase. **Avoid** adapters that merely rename methods of code you own; change the code instead.

## Wrap, extend and simplify

Structural patterns compose objects so interfaces fit together cleanly.

![Three ideas: adapting interfaces, decorating behaviour, simplifying subsystems.](assets/figures/design-patterns/section-4-map.svg) — Figure 4.1 — Adapter, decorator and facade around existing code.

## Adapting an SMS vendor SDK

The vendor client is hypothetical; your app sees only SmsSender.

```typescript
// Our interface
interface SmsSender {
  send(phone: string, text: string): Promise<{ messageId: string }>;
}

// Shape of a (hypothetical) vendor SDK we cannot change
interface VendorSmsClient {
  messages: {
    create(params: { to: string; body: string; from: string }):
      Promise<{ sid: string; status: string }>;
  };
}

class VendorSmsAdapter implements SmsSender {
  constructor(private client: VendorSmsClient, private fromNumber: string) {}

  async send(phone: string, text: string) {
    try {
      const res = await this.client.messages.create({ to: phone, body: text, from: this.fromNumber });
      return { messageId: res.sid };
    } catch (err) {
      throw new SmsDeliveryError('Vendor rejected the message', { cause: err });
    }
  }
}
```

## A travel plug adapter

A plug adapter lets your laptop charger fit a foreign socket without rewiring either the charger or the wall.

**Quiz:** When is an Adapter the right choice?

- [x] When integrating a third-party API whose interface differs from the one your code expects
- [ ] When you need exactly one instance of a class
- [ ] When you want to undo user actions
- [ ] When you need to build an object step by step

*Answer:* When integrating a third-party API whose interface differs from the one your code expects. Adapters translate between interfaces you do not control.
