Understanding Adapter Design Pattern in C#

Salim Alam
2 min readNov 3, 2019

--

As a developer I find the adapter design pattern to be significantly helpful. In this article, I’ll try to help you understand it better.

At first, let us take a look at the ”Gang of four” definition:

Convert the interface of a class into another interface that the clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces.

When I first read the above statement I was confused, I had some idea what the statement was trying to tell but still, it was not clear to me why I would want to change the interface of a class also why a client would have incompatible interfaces.

The second sentence gave me some clue it states about incompatible interfaces. So the interface which is expected by our clients is incompatible with the interface of other class that our client needs to use.

Let me explain to you in more detail. One significant characteristic that is important to the adapter pattern is that the client class take advantage of polymorphism.

Take a look at the following code of our client. [ For simplicity our client is just the main method]

In the above code block, both concrete classes CalculateUsTaxes and CalculateCaTaxes are instantiated against ICalcTax interface.

However, we have a different class TaxCalculateGermany.cs that does not implement the ICalcTax interface but performs the behavior of calculating Tax for Germany that our client class can use. Let us look at the following class.

Since the TaxCalculateGermany.cs is not an implementation of ICalcTax interface our client cannot instantiate it against ICalcTax and continue implementing Polymorphic Behaviour. Therefor inorder to use TaxCalculateGermany class by our client we can create a new adapter class, following is how our adapter class would look like:

Now if we look at our adapter class CalculateDeTax.cs we have implemented the ICalcTax interface and also every time our CalculateDeTax class is instantiated our TaxCalculateGermany class will also be initiated since we are instantiating a new object of TaxCalculateGermany in the constructor of CalculateDeTax class.

This composition of the adaptee and adapter class is a vital characteristic of the adapter design pattern.

Now when our client needs to use TaxCalculateGermany class and its behavior it can instantiate the CalculateDeTax and call the TaxByAnnualSalary method and TaxByAnnualSalary would simply go ahead and call CalculateTax method inside TaxCalculateGermany class.

Our client class now would look something like the following:

To summarize if we have existing objects which can fulfill our requirements do not necessarily adhere to our interface, we can still use the existing objects implementing the Adapter pattern and save ourselves from rewriting the same functionalities.

--

--

Salim Alam

Software Developer, Technical Lead (.Net Technologies)