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