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