For some reason I have thought about good example for Adapter design pattern for a long period of time. There might be straightforward example with two classes, one of which has OperationA and other has OpA and we need to adapt them, but there is no analogy in that example. In this case it would not worse reading this post. Also I thought about example in which we have complex objects with many properties and methods, where you would need to perform some real  conversion. But by the way of thinking there was always electricity adapter in my head circling. In Lviv there is still many apartments where old thin sockets exist, to overcome this people buy small adapters, almost as on the picture on the right, except not that cruel.

So we have our notebook charger that easily fits wide European socket. In your apartment all sockets are new, so you get used to it. Your NewElectricitySystem has method MatchWideSocket. But in your friend’s apartment there is still old one and his OldElectricitySystem has only method MatchThinSocket. Unfortunately you cannot drill sockets in someone else’s flat, you have to buy Adapter, that allows you consume the same electricity, but with old system.

ADAPTER

Adapter – is design pattern that allows us use object, which we cannot change, by providing its functionality thought known interface.

    // Adaptee
    class OldElectricitySystem
    {
        public string MatchThinSocket()
        {
            return "220V";
        }
    }
    // known interface in our code
    interface INewElectricitySystem
    {
        string MatchWideSocket();
    }
    class NewElectricitySystem : INewElectricitySystem
    {
        public string MatchWideSocket()
        {
            return "220V";
        }
    }
    // Adapter
    class Adapter : INewElectricitySystem
    {
        private readonly OldElectricitySystem _adaptee;

        public Adapter(OldElectricitySystem adaptee)
        {
            _adaptee = adaptee;
        }

        // All the magic lives here
        // in our adapter we translate from
        // what we (code) cannot use straightway into what we can
        public string MatchWideSocket()
        {
            return _adaptee.MatchThinSocket();
        }
    }

    class ElectricityConsumer
    {
        // Charging device can be used only with new system
        public static void ChargeNotebook(INewElectricitySystem electricitySystem)
        {
            Console.WriteLine(electricitySystem.MatchWideSocket());
        }
    }

    public class AdapterDemo
    {
        public static void Run()
        {
            // We can easily operate with our new system
            var newElectricitySystem = new NewElectricitySystem();
            ElectricityConsumer.ChargeNotebook(newElectricitySystem);

            // We have to adapt to old system using adapter
            var oldElectricitySystem = new OldElectricitySystem();
            var adapter = new Adapter(oldElectricitySystem);
            ElectricityConsumer.ChargeNotebook(adapter);
        }
    }

Yet another name for this pattern is Wrapper. That is because it wraps functionality of some object, representing it in another interface.

Actually we can also implement it slightly differently than I have it here. In the example above we use composition, but our adapter can easily implement two interfaces of the old and new system and then once created by one of the constructors we would use our adapter in both directions.

My design patterns table

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone