Thursday, 19 February 2015

Adapter Design pattern with example

Adapter Design pattern with examples:

Adapter Pattern comes under the Structural pattern.
Adapter Design pattern work as the bridge between the two incompatible interfaces. I.e. it converts the interface of a class into another interface that clients expect.

What are the uses of the Adapter pattern?
This pattern is used when we need an existing class, and its interface does not match the one we need.

It is also use when we want to create a reusable class that cooperates with unrelated classes, that is, classes that do not necessarily have compatible interfaces.

And also where we need to use several existing subclasses, but it's impractical to adapt their interface by sub classing every one. An object adapter can adapt the interface of its parent class.

In real time example could be a case of card reader, which acts as an adapter between memory card and a laptop. When we plugin the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.

Let us see the simple example that helps us to understand more:


Example for the Adapter design pattern:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
typedef int igCable;

/* Adaptee interface */
class USInterfaceSocket
{
public:
  virtual int voltage () = 0;
  virtual igCable live () = 0;
  virtual igCable neutral () = 0;
  virtual igCable earth () = 0;
};
/* Adaptee */
class MyScocket : public USInterfaceSocket
{
public:
  int voltage ()
    { return 512; }
  igCable live ()
    { return 1; }
  igCable neutral ()
    { return -1; }
  igCable earth ()
    { return 0; }
};

/* Target interface */
class USASocketInterface
{
public:
  virtual int voltage () = 0;
  virtual igCable live () = 0;
  virtual igCable neutral () = 0;
};

/* The Adapter */
class Adapter : public USASocketInterface
{
USInterfaceSocket* socket;
public:
  void plugIn (USInterfaceSocket* pcOutlet)
    { socket = pcOutlet; }
  int voltage ()
    { return 100; }
  igCable live ()
    { return socket->live (); }
  igCable neutral ()
    { return socket->neutral (); }
};

/* Client wants to interact */
class MyElectricBoul
{
  USASocketInterface* power;
public:
  void plugIn (USASocketInterface* supply)
    { power = supply; }
  void boil () {
    if (power->voltage () > 110) {
      std::cout << "Firing!!Please take the precaution" << std::endl;
      return;
    }
    if (power->live () == 1 && power->neutral () == -1)
      { std::cout << "It is a Tea time!" << std::endl;  }
   }
};
int main ()
{
  MyScocket* socket = new MyScocket;
  Adapter* adapter = new Adapter;
  MyElectricBoul* Boul = new MyElectricBoul;

  /* Pluging in. */
  adapter->plugIn (socket);
  Boul->plugIn (adapter);
  /* Having coffee */
  Boul->boil  ();
   getchar ();
   return 0;
}

Points to remember about the Adapter class:
•  Adapter pattern depend on on object composition.
•  Client calls operation on Adapter object.
•  Adapter calls Adaptee to carry out the operation.

No comments: