Adapter Design Pattern (C#)

Introduction

In this article I would try to explore a very useful and commonly used design pattern- "The Adapter Pattern". I will cite my examples using C# language.

Background

Adapter pattern is placed under the category of structural design pattern. “Adapter” as the name suggests is the object which lets two mutually incompatible interfaces communicate with each other. But why we want “someone” to adapt to something? You will get an answer if you answer this simple thing- Your laptop charger which you bought in US has flattish pins which easily gets hooked into electrical sockets in US. But when you travel to European countries you may have round holes in the electrical sockets. What do you do then?-Simple buy socket adapters/converters for that.

We use Adapters when incompatible interfaces are involved. Our client object wants to call a method but it is not able to because the interface which our client object can use, is not available with the code which our client object wants to call. Based on what an adapter does the adapter design pattern is also called wrapper pattern, translator pattern. Let’s look at the various participants (objects, interfaces) involved in an adapter pattern.

ITarget: This is the interface which is used by the client to achieve functionality.<o:p>

Adaptee: This is the functionality which the client desires but its interface is not compatible with the client.<o:p>

Client: This is the class which wants to achieve some functionality by using the adaptee’s code.Adapter: This is the class which would implement ITarget and would call the Adaptee code which the client wants to call.

Using the code

Now let’s look at an example to see how adapter pattern works. Imagine an online shopping portal which displays the products for selling on its home page. These products are coming from a third party vendor with which the portal has tied hands to sell products. The third party vendor already has an inventory system in place which can give the list of products it is selling There is no interface available to online shopping portal with which the portal can call the third party vendor’s inventor code.<o:p>

Since we want to call the third party vendor’s code which is incompatible with client (online shopping portal) code we can apply “Adapter design pattern” here. Let’s first fit in various participants of an adapter pattern in our scenario.<o:p>

ITarget: Method which the online shopping portal calls to get the list of products. Here getting the list of products is the functionality which this portal wants to achieve and this request has been encapsulated in this interface. In short- Functionality to achieve is exposed through this interface.<o:p>

Adaptee: The third party vendor’s code which gives us the list of products.<o:p>

Adapter: The wrapper which would implement ITarget and would call third party vendor’s code.<o:p>

Client: The online shopping portal code which gets the list of products and then displays them.<o:p>

Let’s have a look at the code demonstrating adapter pattern depicting the above scenario then we would revisit the various classes to map them to the adapter pattern participant’s.

In the above code the participants are mapped as:
ITarget: interface ITarget
Adapter: class VendorAdapter, implementing the ITarget interface and acting as a wrapper/link between VendorAdaptee and ShoppingPortalClient.
Adaptee: class VendorAdaptee, this is the code which ShoppingPortalClient is interested in calling.
Client: class ShoppingPortalClient, the client wants to call the code of VendorAdptee.
The code above is self-explanatory, the client which has access to the interface ITarget wants to call the method VendorAdaptee.GetListOfProduct() but since VendorAdaptee does not have an ITarget interface there was a need to create an adapter VendorAdapter. The VendorAdapter implements ITarget interface and calls the method of adaptee.

Based on how the adapter calls the adaptee it can be named as Class Adapter i.e. when the adapter uses class inheritance to call the Adaptee code. It is called Object Adapter when it uses the object composition to call the adaptee code. For example the VendorAdapter shown above is an object adapter because it creates an instance of (object composition) VendorAdaptee.

Points of Interest

The Adapter design pattern is easy to implement and ensures calling the existing code which was otherwise difficult because their interfaces being incompatible. It is quiet common when legacy code has to be called.<o:p>

Share

About the Author

I am a software developer by profession presently working as an Lead Software Engineer in New York City. My passion is technology. I like to learn new things every day and improve my skills in terms of technology. I feel software development can be made very interesting if we inculcate the habit of "beautiful thinking".

I liked very much, the way you explained the pattern, I would love to read from you about more patterns.

I can see for every product the return type of GetProductList() method is List<string>, what would be the solution with this pattern if there is Product class maintained by Adaptee which is different than the Product class returned by ITarget interface for GetProductList() method?

Hi Mamun
Thanks for your encouraging comments.
As far as your question is concerned, you need to understand that we create the Itarget interface based on the adaptee. We try to expose the functionality which the adaptee provides (which was otherwise unavailable) through an interface. So if the adaptee was returning different products in a different format we would expose that return type through an interface.
Hope that explains.