Cover Image

Adapter

Allows objects with incompatible interfaces to collaborate.

classDiagram
    class Client {
        +operation()
    }
    class Target {
        <<interface>>
        +request()
    }
    class Adapter {
        -Adaptee adaptee
        +request()
    }
    class Adaptee {
        +specificRequest()
    }

    Client ..> Target
    Adapter ..|> Target
    Adapter --> Adaptee

When to use

Use the Adapter pattern when you want to use some existing class, but its interface isn’t compatible with the rest of your code. Use when you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass.

Explanation

Problem

Imagine that you’re creating a stock market monitoring app. The app downloads the stock data from multiple sources in XML format and displays nice-looking charts and diagrams for the user. At some point, you decide to improve the app by integrating a smart 3rd-party analytics library. But there’s a catch: the analytics library only works with data in JSON format.

Solution

You can create an adapter. This is a special object that converts the interface of one object so that another object can understand it. An adapter wraps one of the objects to hide the complexity of conversion happening behind the scenes. The wrapped object isn’t even aware of the adapter. For example, you can wrap an object that operates in meters and kilometers with an adapter that converts all of the data to imperial units such as feet and miles.

Real world problem

  1. Power Plug Adapter: You travel from the US to Europe. The plugs are different. You use an adapter.
  2. Data Conversion: Converting XML to JSON, or Legacy API to Modern API.
  3. Database Drivers: A uniform DB interface adapting to specific drivers (MySQL, PostgreSQL).

Pros and Cons

Pros Cons
- Single Responsibility Principle: You can separate the interface or data conversion code from the primary business logic of the program.
- Open/Closed Principle: You can introduce new types of adapters into the program without breaking the existing client code, as long as they work with the adapters through the client interface.
- Complexity: The overall complexity of the code increases because you need to introduce a set of new interfaces and classes. Sometimes it’s simpler just to change the service class so that it matches the rest of your code.

Comparison

  • Bridge: Bridge is usually designed up-front, letting you develop parts of an application independently of each other. Adapter is commonly used with an existing app to make some otherwise-incompatible classes work together well.
  • Decorator: Decorator enhances an object without changing its interface. Adapter changes the interface.
  • Proxy: Proxy has the same interface. Adapter has a different interface.

Code example

Typescript

Php