Search code examples
c#asp.net.netdesign-patternsadapter

what is the need of Adapter Design pattern?


In the below adapter design pattern sample code, why a new class is introduced instead of using multiple interface in the client?

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();
   }
}

I have the below queries related to the above code.

  • What, if ShoppingPortalClient directly inherits VendorAdaptee?
  • In which scenario we need adapter class?
  • why instead of simple inheritance a needed class, creating this pattern to access another class method?

Solution

  • Sometimes you have a given API that you can't change (legacy/external-library/etc...) and you want to make your classes be able to work with that API without changing their code.

    Lets say you use an API which has an ISomethingToSerialize

    public interface ISomethingToSerialize
    {
        object[] GetItemsToSerialize();
    }
    

    That API also has a Serialize function:

    public class SerializationServices
    {
        byte[] Serialize(ISomethingToSerialize objectToSerialize);
    }
    

    Now you have a class in your code, and you don't want or not able to change it, let's call it MyUnchangeableClass.

    This class doesn't implement ISomethingToSerialize but you want to serialize it using the API so you create AdapterClass which implement ISomethingToSerialize to allow MyUnchangeableClass to use it without implementing it by itself:

    public class AdapterClass : ISomethingToSerialize
    {
        public AdapterClass(MyUnchangeableClass instance)
        {
            mInstance = instance;
        }
    
        MyUnchangeableClass mInstance;
    
        public object[] GetItemsToSerialize()
        {
            return mInstance.SomeSpecificGetter();
        }
    }
    

    Now you can use

    MyUnchangeableClass instance = ... //Constructor or factory or something...
    AdapterClass adapter = new AdapterClass(instance)
    SerializationServices.Serialize(adapter);
    

    to serialize an instance of MyUnchangeableClass even though it doesn't meet the requirements of the API by itself.