What is Adapter Design Pattern?

Adapter design pattern falls under the category of the structural design pattern. The main intention of the Adapter pattern is to make two incompatible interfaces compatible so that two different systems can inter-communicate. Two different systems have completely different interfaces to communicate with outside. The underlying classes or objects will not change but there is a middle component, which fixes the incompatibility. This middle component is called as the ‘Adapter’ provides a bridge to eliminate the incompatibilities in two external systems.

GoF definition,

“Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.”

Pattern introduces a component to convert a request from one interface to match with another interface of a totally different system. Both the interfaces are incompatible but the middle component adjusts the request to be compatible with the receiving interface. The middle component called the Adapter and it enables two different interfaces work together to serve a single request.

What is Adapter?

The adapter is the main component in this pattern, which acts as a coordinator between the two incompatible systems. Usually, this will be a class, which contains connection points to both systems. The inner mechanism inside the adapter class will convert the requests from the sending system to match with the receiving system.

 

Adapter Pattern Example

Components of Adapter Pattern

  • Client – Uses the ‘Target’ interface to communicate with the outer world
  • Target – The interface used by the client. This is client domain-specific.
  • Adapter – This is the component which converts the requests and responses as required by the two incompatible systems
  • Adaptee – The interface in the receiving end which associate or inherits from adapter class

Types of Adapters

We can categorize adapters in this pattern according to their implementation approaches. There are two types of adapter implementation strategies to achieve the expected intent of the adapter design pattern.

  1. Class Adapters
  2. Object Adapters

Class Adapters

This is a less used approach due to its limitations in implementation. In this approach, the class ‘Adapter’ sub-classes both ‘Target’ and ‘Adaptee’ interfaces. Adapter class overrides the methods in ‘Target’ interface so that requests can be readily received without any modification. On the other hand, the  ‘Adaptee’ are also sub-classed passing the request right at adapter without delegating. Thus, class adapter approach uses inheritance to implement the code.

 

Apapter Pattern Class Diagram

Object Adapters

These approaches use composition to implement ‘Adapter’ and ‘Adaptee’ relationship while using inheritance to build the ‘Adapter’ and ‘Target’ relationship. In this approach, Adapter class keeps an instance of Adaptee as a class variable. When the client reaches Adapter through the overridden method of Target interface, it uses the Adaptee instance’ internal method to convert and send the message and delegates the original request to the ‘Adaptee’.

object adapter pattern
Object adapter -Class Diagram

Class Adapter vs. Object Adapter

  • Main difference is class adapter uses inheritance to connect Adapter and Adaptee while object adapter uses composition to connect Adapter and Adaptee
  • In class adapter approach, if an Adaptee is a class and not a Java interface Adapter will be a sub-class of Adaptee. Thus it won’t serve all other sub-classes in the same manner since Adapter is a specific concrete sub-class of Adaptee

Why is Object Adapter better?

  • It implements the Target interface allowing programming for interface over implementation
  • It uses composition to keep an instance of Adaptee, allowing single Adapter works with many Adaptee(s) if necessary (Including sub-classes of Adaptee)
  • You can use any Adaptee method inside the Adaptee or their sub-classes to achieve the final result

Two-way Adapters

This is a way to have more transparency on adapter design pattern. Useful when two different clients need to view an object differently. We can create the two-way adapter by implementing the class adapter approach where ‘Adapter’ implements both interfaces of ‘Target’ and ‘Adaptee’. This is a multiple inheritance scenario, which is difficult to implement in languages like Java and C#.

How much Adaption does Adapter Do.

This decides the complexity of the adapter implementation and depends on how similar the Target interface is to the Adaptee. If the mapping operations are complex Adapter has to work hard to make them compatible. You will have to apply a spectrum of operations starting from simple interface implementations to complex new method insertions.

Real Life Example

Most common things related to adapter pattern is the power plugs, which requires when using a device from a different country. You have to use an adapter to make the device’s power code plug compatible with the wall socket or power supply. Also, we can find this in memory card usages. When your device doesn’t have built-in memory card reader, you have to use an adapter to convert the input data readable form the receiving device.

A very simple example would be a language translator. If you are Japanese and you have to talk with Russian, it’s obvious that both don’t understand each other’s languages. Therefore, we have to find a translator who knows both Japanese and Russian. The translator acts as the adapter in this case.

How it Works?

The class adapter will use inheritance, composition or both to implement the inner mechanism. Client sends the request via the Target interface and the Adapter grasps those requests. Then, the Adapter translates those requests into some form, which the Adaptee can understand and passes to the Adaptee. Adaptee gets the modified or converted request and does the necessary job to fulfil the original request from the client.

How to implement Adapter Pattern

  1. Identify the client and its’ interfaces to interact with the external system. If not, create a new interface to interact with the external world. This is the ‘Target’ interface
  2. Identify the service system and the appropriate interfaces or classes to deal with outer world. This is the Adaptee interface or class
  3. Observe the Target and Adaptee to apply a suitable Adapter class
  4. Implement the Adapter class based on interface or composition principles

Example of Adapter Design Pattern

Let’s take the Japanese to Russian translation scenario. Here are the matching components to implement the solution in adapter pattern,

  • Client: Japanese person will be the client in this scenario since he needs to deliver some message to Russian person in order to execute some process steps
  • Target : This is a written idea or verbal instruction set given by the client to the translator and it acts as the interface to the Japanese speaking client
  • Adapter : Translator will be the adapter, which takes the Japanese message from the client end process it inside and convert it to Russian before delivered to the Russian person
  • Adaptee : This is the interface or class maintained by Russian person to receive the converted message from translator

JapaneseTarget.java

TranslatorAdapter.java

RussianAdaptee.java

JapaneseClient.java

When to use Adapter Pattern

  • to connect two incompatible systems with incompatible interfaces
  • to get used of a legacy system but don’t need to know the inner operations.
  • communicating with an external API
  • There’s a requirement of converting interface of a class into another interface that client expects
  • When there is a need to use Open/Closed principle in an application

 

The code in the project can be found here on github

2 thoughts on “What is Adapter Design Pattern?”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.