Jul 13, 2013

Adapter Design Pattern

1 comment
What is Adapter Pattern?
An adapter helps two incompatible interfaces to work together. This is the real world definition for an adapter. Adapter design pattern is used when you want two different classes with incompatible interfaces to work together. The name says it all. Interfaces may be incompatible but the inner functionality should suit the need.
                 In real world the easy and simple example that comes to mind for an adapter is the travel power adapter. American socket and plug are different from India. Those interfaces are not compatible with one another. India plugs are cylindrical and American plugs are rectangular. We can use an adapter in between to fit an American (rectangular) plug in India (cylindrical) socket assuming voltage requirements are met with.
How to implement adapter design pattern?
Adapter design pattern can be implemented in two ways. One using the inheritance method and second using the composition method. Just the implementation methodology is different but the purpose and solution is same.

UML Class Diagram?


Adapter implementation using inheritance
When a class with incompatible method needs to be used with another class, we can use inheritance to create an adapter class. The adapter class which is inherited will have new compatible methods. Using those new methods from the adapter, the core function of the base class will be accessed. This is called “is-a” relationship. The same real world example is implemented in C#.Net as below.

using System;

namespace DesignPatterns.Adapter
{
    public class CylindricalSocket
    {
        public string GetSupply(string cylindWire1, string cylindWire2)
        {
            return "Connected! Power supply is ON.";
        }
    }

    public class RectangularAdapter : CylindricalSocket
    {
        public string GetPowerSupply(string rectWire1, string rectWire2)
        {
            return GetSupply(rectWire1, rectWire2);
        }
    }

    public class RectangularPlug
    {
        private string _rectWire1;
        private string _rectWire2;

        public RectangularPlug(string rectWire1, string rectWire2)
        {
            _rectWire1 = rectWire1;
            _rectWire2 = rectWire2;
        }

        public string GetPowerSupply()
        {
            RectangularAdapter rectAdapter = new RectangularAdapter();
            return rectAdapter.GetPowerSupply(_rectWire1, _rectWire2);
        }
    }

}

Adapter implementation using composition
The above implementation can also be done using composition. Instead of inheriting the base class, create adapter by having the base class as attribute inside the adapter. We can access all the methods by having it as an attribute. This is nothing but “has-a” relationship.

Following example illustrates this approach. Difference is only in the RectangularAdapter class and other two classes are same. In most scenarios, prefer composition over inheritance. Using composition we can change the behavior of class easily if needed. It enables the usage of tools like dependency injection.

namespace DesignPatterns.Adapter
{
    public class CylindricalSocket
    {
        public string GetSupply(string cylindWire1, string cylindWire2)
        {
            return "Connected! Power supply is ON.";
        }
    }

    public class RectangularAdapter        
    {
        private CylindricalSocket _socket;
        public RectangularAdapter()
        {
            _socket = new CylindricalSocket();
        }

        public string GetPowerSupply(string rectWire1, string rectWire2)
        {
            return _socket.GetSupply(rectWire1, rectWire2);
        }
    }

    public class RectangularPlug
    {
        private string _rectWire1;
        private string _rectWire2;

        public RectangularPlug(string rectWire1, string rectWire2)
        {
            _rectWire1 = rectWire1;
            _rectWire2 = rectWire2;
        }

        public string GetPowerSupply()
        {
            RectangularAdapter rectAdapter = new RectangularAdapter();
            return rectAdapter.GetPowerSupply(_rectWire1, _rectWire2);
        }
    }

}

Comparison of classes from the above sample code with UML Class diagram,
Client : RectangularPlug
Adapter : RectangularAdapter
Adaptee : CylindericalSocket

Adapter design pattern in .Net
Data Adapters adapts data from different source (SQL Server, Oracle, ODBC and OLE DB) to dataset which is data-source unaware.

Different Data Adapter classes used are,
  • SqlDataAdapter
  • OdbcDataAdapter
  • OleDbDataAdapter

1 comment :