Оглавление:
Карта сайта:
Оглавление:
Карта сайта:
Шаблон адаптера позволяет обернуть несовместимый объект в адаптер, чтобы сделать его совместимым с другим классом.
Чаще всего «Адаптер» применяется, если необходимо создать определенный класс, производный от уже существующего.
Привести нестандартный или неудобный интерфейс какого-то класса в интерфейс, совместимый с вашим кодом. Адаптер
позволяет классам работать вместе стандартным образом, что обычно не получается из-за несовместимых интерфейсов,
предоставляя для этого прослойку с интерфейсом, удобным для клиентов, самостоятельно используя оригинальный интерфейс.
Использование:
причём расширить суперкласс вы не можете.
Преимущества:
Недостатки:
Связи с другими паттернами
Adapter.php
<?php interface NativeWorker { public function countSalary(): int; } interface OutsourceWorker { public function countSalaryByHour($hours): int; } class NativeDeveloper implements NativeWorker { public function countSalary(): int { return 3000 * 20; } } class OutsourceDeveloper implements OutsourceWorker { public function countSalaryByHour($hours): int { return $hours * 300; } } class OutsourceWorkerAdapter implements NativeWorker { private OutsourceWorker $outsourceWorker; public function __construct(OutsourceWorker $outsourceWorker) { $this->outsourceWorker = $outsourceWorker; } public function countSalary(): int { return $this->outsourceWorker->countSalaryByHour(40); } } $nativeDeveloper = new NativeDeveloper(); echo $nativeDeveloper->countSalary(); // 60000 $outsourceDeveloper = new OutsourceDeveloper(); echo $outsourceDeveloper->countSalaryByHour(40); //12000 $outsourceWorkerAdapter = new OutsourceWorkerAdapter($outsourceDeveloper); echo $outsourceWorkerAdapter->countSalary(); // 12000 // ----------- 2 ----------- interface Book { public function turnPage(); public function open(); public function getPage(): int; } class PaperBook implements Book { private int $page; public function open(): void { $this->page = 1; } public function turnPage(): void { $this->page++; } public function getPage(): int { return $this->page; } } interface EBook { public function unlock(); public function pressNext(); /** * возвращает текущую страницу и общее количество страниц, например [10, 100] - страница 10 из 100 * * @return int[] */ public function getPage(): array; } /** * Вот этот адаптер. Обратите внимание, что в нем реализована книга, * таким образом, вам не нужно изменять код клиента, который использует книгу */ class EBookAdapter implements Book { public function __construct(protected EBook $eBook) { } /** * Этот класс выполняет надлежащий перевод с одного интерфейса на другой. */ public function open() { $this->eBook->unlock(); } public function turnPage() { $this->eBook->pressNext(); } /** * обратите внимание на адаптированное поведение здесь: eBook::getPage() вернет два целых числа, но Book * поддерживает только средство получения текущей страницы, поэтому мы адаптируем поведение здесь */ public function getPage(): int { return $this->eBook->getPage()[0]; } } /** * это адаптированный класс. В производственном коде это может быть класс из другого пакета, какой-нибудь код поставщика. * Обратите внимание, что он использует другую схему именования, и реализация делает нечто подобное, но другим способом */ class Kindle implements EBook { private int $page = 1; private int $totalPages = 100; public function pressNext() { $this->page++; } public function unlock() { } /** * возвращает текущую страницу и общее количество страниц, например [10, 100] - страница 10 из 100 * * @return int[] */ public function getPage(): array { return [$this->page, $this->totalPages]; } } $book = new PaperBook(); $book->open(); $book->turnPage(); echo $book->getPage(); // 2 $kindle = new Kindle(); $kindle->unlock(); $kindle->pressNext(); print_r($kindle->getPage()); // [0] => 2 // [1] => 100 $kindle2 = new Kindle(); $book2 = new EBookAdapter($kindle2); $book2->open(); $book2->turnPage(); $book2->turnPage(); echo $book2->getPage(); // 3