Tuesday, February 09, 2010

Design patterns : Adapter Design Pattern

Adapter design pattern converts the interface of a class into another interface that the client expects. It lets the classes work together that otherwise could not because of incompatible interfaces. It wraps the existing class in a compatible interface acceptible to the the client.

The actors here are the client - which makes use of an object which implements the target interface, the target is the point of extension of the client module, adaptee - object of different module or library and the adapter is an implementation of the target which forwards real work to the adaptee and also hides him from the client.

PHP Code :

class SimpleBook
{
  private $author;
  private $title;
  function __construct($author_in, $title_in)
  {
    $this->author = $author_in;
    $this->title  = $title_in;
  }
  function getAuthor()
  {
    return $this->author;
  }
  function getTitle()
  {
    return $this->title;
  }
}

class BookAdapter
{
  private $book;
  function __construct(SimpleBook $book_in)
  {
    $this->book = $book_in;
  }
  function getAuthorAndTitle()
  {
    return $this->book->getTitle().' by '.$this->book->getAuthor();
  }
}

// client

echo "BEGIN\n";

$book = new SimpleBook("PHP Author", "PHP Book on Design patterns");
$bookAdapter = new BookAdapter($book);
echo "Author and Title: ".$bookAdapter->getAuthorAndTitle()."\n";

echo "END\n";

Output:

BEGIN
Author and Title: PHP Book on Design patterns by PHP Author
END

JAVA Code:

class LegacyLine
{
  public void draw(int x1, int y1, int x2, int y2)
  {
    System.out.println("line from (" + x1 + ',' + y1 + ") to (" + x2 + ','  + y2 + ')');
  }
}

class LegacyRectangle
{
  public void draw(int x, int y, int w, int h)
  {
    System.out.println("rectangle at (" + x + ',' + y + ") with width " + w  + " and height " + h);
  }
}

interface Shape
{
  void draw(int x1, int y1, int x2, int y2);
}

class Line implements Shape
{
  private LegacyLine adaptee = new LegacyLine();
  public void draw(int x1, int y1, int x2, int y2)
  {
    adaptee.draw(x1, y1, x2, y2);
  }
}

class Rectangle implements Shape
{
  private LegacyRectangle adaptee = new LegacyRectangle();
  public void draw(int x1, int y1, int x2, int y2)
  {
    adaptee.draw(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1),   Math.abs(y2 - y1));
  }
}

public class AdapterDemo
{
  public static void main(String[] args)
  {
    Shape[] shapes = 
    {
      new Line(), new Rectangle()
    };
    // A begin and end point from a graphical editor
    int x1 = 10, y1 = 20;
    int x2 = 30, y2 = 60;
    for (int i = 0; i < shapes.length; ++i)
      shapes[i].draw(x1, y1, x2, y2);
  }
}

Output : 

line from (10,20) to (30,60)
rectangle at (10,20) with width 20 and height 40

No comments: