2.1. Adapter / Wrapper

2.1.1. Amaç

Bir sınıfın bir arayüzünü uyumlu bir arayüze çevirmek. Bir uyarlayıcı, normalde uyumsuz olan orijinal arayüzleri nedeniyle birlikte çalışamayacak olan nesnelerin, kendi arayüzünü istemcilerin kullanımına sunarak, birlikte çalışmalarını sağlar.

2.1.2. Örnekler

  • Veritabanı İstemcisi (Database Client) kütüphaneleri içindeki uyarlayıcılar (örn. OppaAgentAgent).

  • Birden çok ve farklı ağ servisi (web service) ve uyarlayıcısı kullanıldığında, veriler normalleştirildiğinden sonuç herkes için aynıdır.

2.1.3. UML Diyagramı

Alt Adapter UML Diyagramı

2.1.4. Kod

Bu kodu Github üzerinde de bulabilirsiniz.

Book.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter;
 6
 7interface Book
 8{
 9    public function turnPage();
10
11    public function open();
12
13    public function getPage(): int;
14}

PaperBook.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter;
 6
 7class PaperBook implements Book
 8{
 9    private int $page;
10
11    public function open(): void
12    {
13        $this->page = 1;
14    }
15
16    public function turnPage(): void
17    {
18        $this->page++;
19    }
20
21    public function getPage(): int
22    {
23        return $this->page;
24    }
25}

EBook.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter;
 6
 7interface EBook
 8{
 9    public function unlock();
10
11    public function pressNext();
12
13    /**
14     * returns current page and total number of pages, like [10, 100] is page 10 of 100
15     *
16     * @return int[]
17     */
18    public function getPage(): array;
19}

EBookAdapter.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter;
 6
 7/**
 8 * This is the adapter here. Notice it implements Book,
 9 * therefore you don't have to change the code of the client which is using a Book
10 */
11class EBookAdapter implements Book
12{
13    public function __construct(protected EBook $eBook)
14    {
15    }
16
17    /**
18     * This class makes the proper translation from one interface to another.
19     */
20    public function open()
21    {
22        $this->eBook->unlock();
23    }
24
25    public function turnPage()
26    {
27        $this->eBook->pressNext();
28    }
29
30    /**
31     * notice the adapted behavior here: EBook::getPage() will return two integers, but Book
32     * supports only a current page getter, so we adapt the behavior here
33     */
34    public function getPage(): int
35    {
36        return $this->eBook->getPage()[0];
37    }
38}

Kindle.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter;
 6
 7/**
 8 * this is the adapted class. In production code, this could be a class from another package, some vendor code.
 9 * Notice that it uses another naming scheme and the implementation does something similar but in another way
10 */
11class Kindle implements EBook
12{
13    private int $page = 1;
14    private int $totalPages = 100;
15
16    public function pressNext()
17    {
18        $this->page++;
19    }
20
21    public function unlock()
22    {
23    }
24
25    /**
26     * returns current page and total number of pages, like [10, 100] is page 10 of 100
27     *
28     * @return int[]
29     */
30    public function getPage(): array
31    {
32        return [$this->page, $this->totalPages];
33    }
34}

2.1.5. Test

Tests/AdapterTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Structural\Adapter\Tests;
 6
 7use DesignPatterns\Structural\Adapter\PaperBook;
 8use DesignPatterns\Structural\Adapter\EBookAdapter;
 9use DesignPatterns\Structural\Adapter\Kindle;
10use PHPUnit\Framework\TestCase;
11
12class AdapterTest extends TestCase
13{
14    public function testCanTurnPageOnBook()
15    {
16        $book = new PaperBook();
17        $book->open();
18        $book->turnPage();
19
20        $this->assertSame(2, $book->getPage());
21    }
22
23    public function testCanTurnPageOnKindleLikeInANormalBook()
24    {
25        $kindle = new Kindle();
26        $book = new EBookAdapter($kindle);
27
28        $book->open();
29        $book->turnPage();
30
31        $this->assertSame(2, $book->getPage());
32    }
33}