Adapters are something that most of use or at least see almost on daily basis. They can be loosely defined as devices that can make 2 or more components with incompatible interfaces work together. Below is one of the most commonly used type of adapter which enables an electric plug to plug into an incompatible power socket. Image credits: powercord9, tuxgraphics.

So now if we extend the use of adapters to software design, then
An adapter is a software component that converts interface of a class to an interface that client expects, thus allowing classes with different interfaces to work together. The pattern of creating adapters is called Adapter Patern.
Below class diagram depicts a general implementation of adapter pattern.

- Here Client needs to call/ use some methods/ operations on a class/ library denoted by Adaptee.
- But the interface or the method definitions of the Adaptee are not what the Client is expecting.
- So, we introduce an Adapter, which is typically an interface that defines adapter operations, operations the Client can work with.
- Then we have a ConcreteAdapter, a class that is the concrete implementation of the adapter interface. This class creates an Adaptee object and calls its operations.
- The Client now calls the Adapter operations by creating a ConcreteAdapter object, which in turn calls the operations on the Adaptee.
- Thus, the Adapter provides a way for the Client to call Adaptee operations even though the Client can’t use the Adaptee directly.
To understand better, consider the below e.g.

- Let’s say we have a client program with a method UseDataTable, that expects an parameter of type DataTable.
- Now assume that we have an external library JsonConverter that reads data from any data source of any type and converts it to Json. Similarly, we also have XmlConverter.
- For our example our converter libraries will read .csv data from a local file.
- As we can see, to use the converters, our client program must implement logic to convert Json and Xml to DataTable.
Well, this seems like a perfectly fine example, but there are a few issues here:
- Every client program that expects a DataTable and uses JsonConverter &/ or XmlConverter will have to write its own logic to generate a DataTable.
- This will not only cause code repetition, but will also cause maintenance issues.
- Any change to conversion logic will have to be replicated in every client.
So, we have a classic case for adapter pattern implementation where our client program needs to use the converter libraries but can’t do it efficiently because it can’t work with libraries’ current interface. Lets apply adapter pattern to our scenario and see how it can help us.

- Here, we have added adapter pattern to our application and added an interface, IFormatAdapter, that defines our adapter.
- Class JsonAdapter implements IFormatAdapter and converts Json to DataTable. To get Json, it relies on the library/ class JsonConverter. This means that JsonAdapter creates an object of JsonConverter and calls it’s method GetJson.
- Similarly, XmlAdapter implements IFormatAdapter and converts Xml, returned by XmlConverter, to DataTable.
- Now, the client is neither dependent on JsonConverter or XmlConverter nor it requires to have logic to convert Json/ Xml to DataTable.
- Client can create an object type IFormatAdapter and instantiate it to the required adapter, in our case JsonAdapter or XmlAdapter.
The advantages of adding an adapter to our design are:
- Client can use the converters without worrying about the interface they expose or about implementing any complex conversion logic.
- Multiple clients can use the data adapter IFormatAdapter and have same functionality.
- This allows for consistency to be maintained and also improves the maintainability.
- Suppose any new type of converter is added, a new data adapter implementing IFormatAdapter can be created. This allows us to extend the adapter functionality without affecting the existing code. This is a perfect example of Open-Closed Principle in use.