Pattern Name:

Adapter Pattern

Short Description:

Match interfaces of classes with different interfaces

Usage:

Often used and easy to implement, useful if classes need to work together that have incompatible existing interfaces.

Complexity:

1 / 5

UML Class Diagram:

image

Explanation:

  • The TradingDataImporter class acts as a client using classes with an existing Connector interface.
    public class TradingDataImporter
    {
        public void ImportData(Connector connector)
        {
            connector.GetData();
        }
    }

  • The abstract Adapter class defines the interface that the client class knows and that it can work with.

  • The concrete Adapter classes convert the interface of the incompatible classes into an interface the client expects. They make different existing interfaces work together.

    public abstract class Connector
    {
        public abstract void GetData();
    }

    public class DatabaseConnector : Connector
    {
        public override void GetData()
        {
            var databaseHelper = new DatabaseHelper();
            databaseHelper.QueryForChanges();
        }
    }

    public class XmlFileConnector : Connector
    {
        public override void GetData()
        {
            var xmlfileLoader = new XmlFileLoader();
            xmlfileLoader.LoadXML();
        }
    }

    public class HttpStreamConnector : Connector
    {
        public override void GetData()
        {
            var websiteScanner = new WebSiteScanner();
            websiteScanner.Scan();
        }
    }
  • Here are some examples of different adaptee classes that implement different interfaces. However, the client expects a generic interface that they currently don’t provide. That is why they get wrapped by the concrete adapter classes to make them compatible with the client.
    public class DatabaseHelper
    {
        public void QueryForChanges()
        {
            Console.WriteLine("Database queried.");
        }
    }

    public class WebSiteScanner
    {
        public void Scan()
        {
            Console.WriteLine("Web sites scanned.");
        }
    }

    public class XmlFileLoader
    {
        public void LoadXML()
        {
            Console.WriteLine("Xml files loaded.");
        }
    }
  • In the last step we add some code to test the software design and the Adapter implementation.
    public static void Adapter()
    {
        var tradingdataImporter = new TradingDataImporter();

        Connector databaseConnector = new DatabaseConnector();
        tradingdataImporter.ImportData(databaseConnector);

        Connector xmlfileConnector = new XmlFileConnector();
        tradingdataImporter.ImportData(xmlfileConnector);

        Connector httpstreamConnector = new HttpStreamConnector();
        tradingdataImporter.ImportData(httpstreamConnector);           

        Console.ReadKey();
    }
  • When running the example you can see that everything is working as expected and that the correct classes are instantiated during runtime.

image

Last edited Jul 18, 2011 at 2:47 PM by JasonOliveira, version 4

Comments

FinestSolution Feb 3, 2014 at 8:41 PM 
One of the benefits of using design patterns is recognizable vocabulary. So when working on someone else's code you can easily see the design patterns used just by looking at the class names.
In your example of Adapter pattern you named your adapter "Connector". In my opinion - this is misleading name. If I was using your sample in real life I would name "Connentor" as TradingDataAdapter

Lakshas May 11, 2013 at 7:12 PM 
Correct me if I'm wrong.Though it allows interface of class, during the implementation it has most resemblance with Factory pattern.