Skip to content

Adapter Design Pattern

Structural design pattern

Structural pattern

Adapter design pattern allows objects with incompatible interfaces to collaborate.

It’s easier to explain the problem with an example.

Imagine you develop an application that relies on data stored in XML format. At some point, the app needs to interact with an 3rd-party library that only works with JSON format. You cannot change your app’s codebase to work with JSON nor change the library to work with XML data.

You can create an adapter: 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.

Adapters can both convert data into various formats and also help objects with different interfaces collaborate.

Sometimes it’s even possible to create a two-way adapter that can convert the calls in both directions.

Use the Adapter class when you want to use some existing class, but its interface isn’t compatible with the rest of your code.

Use the pattern when you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass.

The steps to implement Adapter pattern are:

  1. Make sure that you have at least two classes with incompatible interfaces: a useful service class, one (or several) client classes that would benefit from using the service class.
  2. Declare the client interface and describe how clients communicate with the service.
  3. Create the adapter class and make it follow the client interface.
  4. Add a field to the adapter class to store a reference to the service object. You should initialize this field via the constructor, but sometimes it’s more convenient to pass it to the adapter when calling its methods.
  5. One by one, implement all methods of the client interface in the adapter class. The adapter should delegate most of the real work to the service object, handling only the interface or data format conversion.
  6. Clients should use the adapter via the client interface. This will let you change or extend the adapters without affecting the client code.
Pros
  1. Single Responsibility Principle: you can separate the interface or data conversion code from the primary business logic of the program.
  2. 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.
ConsThe 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.