Adapter Design Pattern (C#)






4.95/5 (29 votes)
The article explains Adapter pattern, implemented in 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.
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.
interface ITarget
{
List<string> GetProducts();
}
public class VendorAdaptee
{
public List<string> GetListOfProducts()
{
List<string> products = new List<string>();
products.Add("Gaming Consoles");
products.Add("Television");
products.Add("Books");
products.Add("Musical Instruments");
return products;
}
}
class VendorAdapter:ITarget
{
public List<string> GetProducts()
{
VendorAdaptee adaptee = new VendorAdaptee();
return adaptee.GetListOfProducts();
}
}
class ShoppingPortalClient
{
static void Main(string[] args)
{
ITarget adapter = new VendorAdapter();
foreach (string product in adapter.GetProducts())
{
Console.WriteLine(product);
}
Console.ReadLine();
}
}
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.
History
Version 1 (16/5/2014)