Done!

The Adapter Pattern - Design Pattern in PHP


Adapter pattern allows us convert or translate one interface to another.

Say, we have a Book Class

interface BookInterface
{
  public function open();
  public function turnPage();
}

class Book implements BookInterface {
  public function open() {
      var_dump("opening of the book");
  }

  public function turnPage() {
      var_dump("turning of a page");
  }
}

//Consume the class
class Person {
  public function read(BookInterface $book) {
    $book->open();
    $book->turnPage();
  }  
}

(new Person)->read(new Book);

Lets further assume, more people are using Kindle and Nook. Both of them are supplied by the external vendor and its interface doesn't match with our Book Interface:

interface eReaderInterface{
    public function switchOn();
    public function pressNextButton();
}

class Kindle implements eReaderInterface {
  public function switchOn() {
      var_dump("switching on the kindle");
  }

  public function pressNextButton()
  {
      var_dump("clicking kindle button");
  }
}

class Nook implements eReaderInterface {
  public function switchOn()
  {
      var_dump("turning on the nook");
  }

  public function pressNextButton()
  {
      var_dump("Pressing Next Button on the nook");
  }
}

If a Person Class need to use Kindle and Nook, without changing the Person Class - we need to create an adapter so that these two interface can communicate with each other

/** 
  * Adapter must Implements the interface that it is trying to adhere to, in this case BookInterface
  */
class eReaderAdapter extends BookInterface {
  /**
   * On the constructor we need to inject the interface we need to translate
   */
  public function __construct(eReaderInterface $eReaderInterface) {
    $this->eReaderInterface = $eReaderInterface;
  }

  public function open() {
    $this->eReaderInterface->switchOn();
  }

  public function turnPage()
  {
    $this->eReaderInterface->pressNextButton();
  }
}

Implementation:

echo (new Person())->read(new Book);

echo (new Person())->read(new eReaderAdapter(new Kindle));

echo (new Person())->read(new eReaderAdapter(new Nook));

Key Points:

1. The adapter must implement the interface that it is trying to adapt.

2. Inject a class or interface into a constructor and translate the original method to a new one