Adapter Design Pattern in C#

Adapter Design Pattern in C# with Examples

In this article, I am going to discuss the Adapter Design Pattern in C# with examples. Please read our previous article where we discussed the basics of the Structural Design Pattern in C#. The Adapter Design Pattern falls under the category of Structural Design Pattern. As part of this article, we are going to discuss the following pointers.

  1. What is the Adapter Design Pattern?
  2. Examples to understand Object and Class Adapter Pattern in C#.
  3. When to use the Adapter Design Pattern in C#?
  4. When to use the Object Adapter pattern and when to use Class Adapter Pattern?
What is the Adapter Design Pattern?

As per the GOF definition, the adapter design pattern allows two incompatible interfaces to work together. That means it allows the interface of an existing class to be used from another interface. It is often used to make existing classes work with others without modifying their source code. If this is not clear at the moment then don’t worry we will understand this with some examples.

Example:

The best example of the adapter design pattern is based around an AC power adapter. The AC power adapter knows how to deal with both sides. That means it acts as a middleman.

In real-time applications, you may have two classes incompatible because of the incompatible interfaces. Let us understand this with an example. Please have a look at the following image.

Adapter Design Pattern in C# Methods are not compatible

As you can see in the above image, both the classes are having the same signature i.e. both the classes having one method. The methods are also going to do the same operation i.e. returning some string data. But the above two classes are not compatible in terms of method names.

When you have two classes with the same signature and if the two classes are going to perform a similar kind of operation but the names are different then in such scenarios to make the classes are compatible with each other we need to use the Adapter Design Pattern.

The Adapter Design Pattern in C# helps us to wrap a class around the existing class and make the classes compatible with each other. There are two ways to make the above two classes compatible with each other. They are as follows.

  1. Object Adapter Pattern
  2. Class Adapter Pattern
Object Adapter Pattern

Please have a look at the following diagram which shows how to make the above two classes compatible using Object Adapter Pattern.

Object Adapter Design Pattern in C#

Here, we created a new class with the name GetDataAdapter. This class inherits from the GetDataClass and override the GetData method. As part of the GetDataAdapter class, we created an instance of the NewGetDataCass and then invoke the NewGetData method within the GetData method. Now, the GetDataAdapter class is a wrapper for our NewGetDataClass and it is now compatible with the GetDataClass.

The complete code is given below. The program is self-explained so, please go through the comment lines.

using System;
namespace AdapterDesignPattern
{
    // This is the class which provides the functionalities and used by the client.
    public class GetDataClass
    {
        public virtual string GetData()
        {
            return "GetData Method called";
        }
    }

    // Adaptee: The NewGetDataClass contains the functionality which the client desires 
    // but its method signature is not compatible with the existing client code. 
    // The NewGetDataClass needs some adaptation before the client code can use it.
    public class NewGetDataClass
    {
        public virtual string NewGetData()
        {
            return "NewGetData Method called";
        }
    }

    // Adapter: This is the class which makes the NewGetDataClass class compatible with the client
    // interface which the client wants to call.
    public class GetDataAdapter : GetDataClass
    {
        private NewGetDataClass newGetDataObject = new NewGetDataClass();

        public override string GetData()
        {
            return newGetDataObject.NewGetData();
        }
    }
 
    // The Client class
    public class Program
    {
        static void Main(string[] args)
        {
            // The GetDataAdapter class is compatible with the client code.
            // So, the client will use the GetDataAdapter instance to call functionality 
            // of Adaptee (NewGetDataClass) class
            GetDataAdapter obj1 = new GetDataAdapter();
            Console.WriteLine(obj1.GetData());

            //You can still use the GetDataClass as shown below
            GetDataClass obj2 = new GetDataClass();
            Console.WriteLine(obj2.GetData());

            Console.Read();
        }
    }
}
Class Adapter Pattern

Please have a look at the following diagram which shows how to make the classes are compatible using Class Adapter Pattern.

Class Adapter Design Pattern in C#

As you can see now the GetDataAdapter method is inherited from the NewGetDataClas. As part of the GetDataAdapter class, we create the GetData method which internally calls the base class NewGetData method. Now both the classes are compatible in terms of the method name.

The complete code is given below.

using System;
namespace AdapterDesignPattern
{
    public class GetDataClass
    {
        public virtual string GetData()
        {
            return "GetData Method called";
        }
    }
    
    public class NewGetDataClass
    {
        public virtual string NewGetData()
        {
            return "NewGetData Method called";
        }
    }
    
    public class GetDataAdapter : NewGetDataClass
    {
        public string GetData()
        {
            return this.NewGetData();
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            GetDataAdapter obj1 = new GetDataAdapter();
            Console.WriteLine(obj1.GetData());

            //You can still use the GetDataClass as shown below
            GetDataClass obj2 = new GetDataClass();
            Console.WriteLine(obj2.GetData());

            Console.Read();
        }
    }
}
When to use the Object Adapter pattern and when to use Class Adapter Pattern?

It is completely based on the situations. For example, if you have a java class and you want to make it compatible with dot net class, then you need to use the object adapter pattern and the reason is it is not possible to make inheritance. On the other hand, if both the classes are within the same project and using the same programming language and if the inheritance is possible then you need to go for Class Adapter Pattern.

When to use the Adapter Design Pattern in C#?

We need to choose the Adapter Design Pattern in C# when

  1. A class needs to be reused that does not have an interface that a client requires.
  2. We need to work through a separate Adapter that adapts the interface of an  existing class without changing it
  3. Clients don’t know whether they work with a Target class directly or through an Adapter with a class that does not have the Target interface

In the next article, I am going to discuss the Facade Design Pattern in C# with some examples. Here, in this article, I try to explain the basics of the Adapter Design Pattern step by step with some simple examples. I hope you understood the need and use of the Adapter Design Pattern in C#.

Leave a Reply

Your email address will not be published. Required fields are marked *