Purpose:
To translate one interface for a class into a compatible interface. An adapter allows classes to work together that normally could not because of incompatible interfaces by providing its interface to clients while using the original interface.
BookInterface.php
<?php
namespace DesignPatterns\Structural\Adapter;
interface BookInterface
{
public function trunPage();
public function open();
public function getPage(): int;
?>
Book.php
<?php
namespace DesignPatterns\Structural\Adapter;
class Book implements BookInterface
{
/**
* Varibles Description
*
* @var int
*/
private $page;
/**
* Open the book
*
* @return Void
*/
public function open()
{
$this->page = 1;
}
/**
* Turn pages
*
* @return Void
*/
public function turnPage()
{
$this->page++;
}
/**
* Get total number of pages
*
* @return Int
*/
public function getPage(): int
{
return $this->page;
}
}
?>
EBookAdapter.php
<?php
namespace DesignPatterns\Structural\Adapter;
/**
* This is the adapter here. Notice it implements BookInterface,
* therefore you don't have to change the code of the client which is using a Book
*/
class EBookAdapter implements BookInterface
{
/**
* eBook
*
* @var EBookInterface
*/
protected $eBook;
/**
* Constructor
*
* @return Void
*/
public function __construct(EBookInterface $eBook)
{
$this->eBook = $eBook;
}
/**
* This class makes the proper translation from one interface to another
*
* @return Void
*/
public function open()
{
$this->eBook->unlock();
}
/**
* This class makes the paper translation from one interface to another
*
* @return Void
*/
public function turnPage()
{
$this->eBook->pressNext();
}
/**
* notice the adapted behavior here: EBookInterface::getPage() will return two integers, but BookInterface
* supports only a current page getter, so we adapt the behavior here
*
* @return Int
*/
public function getPage(): int
{
return $this->eBook->getPage()[0];
}
}
?>
EBookInterface.php
<?php
namespace DesignPatterns\Structural\Adapter;
interface EBookInterface
{
public function unlock();
public function pressNext();
/**
* returns current page and total number of pages, like [10, 100] is page 10 of 100
*
* @return int[]
*/
public function getPage(): array;
}
?>
Kindle.php
<?php
namespace DesignPatterns\Structural\Adapter;
/**
* this is the adapted class. In production code, this could be a class from another package, some vendor code.
* Notice that it uses another naming scheme and the implementation does something similar but in another way
*/
class Kindle implements EBookInterface
{
/**
* Varibles Description
*
* @var int
*/
protected $page = 1;
/**
* Varibles Description
*
* @var int
*/
private $totalPages = 100;
/**
* Function Description
*
* @return Void
*/
public function pressNext()
{
$this->page++;
}
/**
* Function Description
*
* @return Int
*/
public function unlock()
{
}
/**
* Function Description
*
* @return array
*/
public function getPage(): array
{
return [$this->page, $this->totalPages];
}
}
?>
Tests/AdapterTest.php
<?php
namespace DesignPatterns\Structural\Adapter\Tests;
use DesignPatterns\Structural\Adapter\Book;
use DesignPatterns\Structural\Adapter\EBookAdapter;
use DesignPatterns\Structural\Adapter\Kindle;
use PHPUnit\Framework\TestCase;
class AdapterTest extends TestCase
{
public function testCanTurnPageOnBook()
{
$book = new Book();
$book->open();
$book->turnPage();
$this->assertEquals(2, $book->getPage());
}
public function testCanTurnPageOnKindleLikeInANormalBook()
{
$kindle = new Kindle();
$book = new EBookAdapter($kindle);
$book->open();
$book->turnPage();
$this->assertEquals(2, $book->getPage());
}
}