适配器模式
目的
将一个类的接口转换成一个兼容的接口。当使用类的原接口的时候,适配器通过向客户端提供一个接口,可以让原本不兼容的类一起工作。
使用场景
- 数据库客户端适配器
- 使用多个不同的 WebService 和适配器对数据进行统一处理,以保证所有的结果都一样
UML 类图

代码
Book.php
1 2 3 4 5 6 7 8 9 10 11 12
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter;
interface Book { public function turnPage();
public function open();
public function getPage(): int; }
|
PaperBook.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter;
class PaperBook implements Book { private int $page;
public function open() { $this->page = 1; }
public function turnPage() { $this->page++; }
public function getPage(): int { return $this->page; } }
|
EBook.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter;
interface EBook { public function unlock();
public function pressNext();
public function getPage(): array; }
|
EBookAdapter.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter;
class EBookAdapter implements Book { protected EBook $eBook;
public function __construct(EBook $eBook) { $this->eBook = $eBook; }
public function open() { $this->eBook->unlock(); }
public function turnPage() { $this->eBook->pressNext(); }
public function getPage(): int { return $this->eBook->getPage()[0]; } }
|
Kindle.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter;
class Kindle implements EBook { private int $page = 1; private int $totalPages = 100;
public function pressNext() { $this->page++; }
public function unlock() { }
public function getPage(): array { return [$this->page, $this->totalPages]; } }
|
测试
Tests/AdapterTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?php declare(strict_types = 1);
namespace DesignPatterns\Structural\Adapter\Tests;
use DesignPatterns\Structural\Adapter\PaperBook; use DesignPatterns\Structural\Adapter\EBookAdapter; use DesignPatterns\Structural\Adapter\Kindle; use PHPUnit\Framework\TestCase;
class AdapterTest extends TestCase { public function testCanTurnPageOnBook() { $book = new PaperBook(); $book->open(); $book->turnPage();
$this->assertSame(2, $book->getPage()); }
public function testCanTurnPageOnKindleLikeInANormalBook() { $kindle = new Kindle(); $book = new EBookAdapter($kindle);
$book->open(); $book->turnPage();
$this->assertSame(2, $book->getPage()); } }
|