2014-12-23 3 views
0

Я немного смущен концепцией адаптера. Я нахожу, что классы адаптера очень похожи на расширенные классы, которые я бы написал обычно. Итак, каковы отличия между ними на самом деле?PHP шаблоны проектирования - наследование против шаблона адаптера?

Например (пример из этого link),

SimpleBook.php,

class SimpleBook { 


    private $author; 
    private $title; 


    function __construct($author_in, $title_in) { 
     $this->author = $author_in; 
     $this->title = $title_in; 
    } 


    function getAuthor() {return $this->author;} 


    function getTitle() {return $this->title;} 


    } 

BookAdapter.php

include_once('SimpleBook.php'); 

    class BookAdapter { 


    private $book; 


    function __construct(SimpleBook $book_in) { 
     $this->book = $book_in; 
    } 


    function getAuthorAndTitle() { 
     return $this->book->getTitle() . ' by ' . $this->book->getAuthor(); 
    } 


    } 

BookExtension.php,

include_once('SimpleBook.php'); 

     class BookExtension extends SimpleBook{ 

     function getAuthorAndTitle() { 
      return $this->getTitle() . ' by ' . $this->getAuthor(); 
     } 


     } 

Второе решение кажется намного проще. Так ли это (и других классов наследования в целом) считается адаптер класс тогда?

ответ

0

Разница связана с тем, как классы могут использоваться с полиморфизмом.

Если вы используете наследование, любая функция, ожидающая SimpleBook, также примет BookExtension или любой другой класс, который расширяет SimpleBook. Например, если у вас:

function PigLatinTitle(SimpleBook $b) { 
    return PigLatin($b->getTitle()); 
} 

вы можете вызвать эту функцию на BookExtension, потому что он наследует метод SimpleBook::getTitle().

Обратите внимание, что это не работает наоборот: функция, которая ожидает, что BookExtension не будет работать с SimpleBook. Например, если функция вызывает getAuthorAndTitle(), это произойдет, если аргумент SimpleBook, потому что там нет такого метода.

Если вы используете адаптер, два класса являются независимыми. Функции, ожидающие SimpleBook, не принимают BookAdapter и наоборот. Вы не можете позвонить PigLatinTitle() по телефону BookAdapter, потому что нет метода BookAdapter::getTitle().

Вы можете сделать адаптер работать как наследование путем добавления метода в __call() магии BookAdapter, а затем повторно вызвать метод на $this->book:

public function __call($name, $arguments) { 
    return call_user_func_array(array($this->book, $name), $arguments); 
} 
+0

Спасибо за ответ. Я немного смущен: «Если вы используете наследование, любая функция, которая ожидает, что SimpleBook также примет BookExtension или любой другой класс, который расширяет SimpleBook». Я думал, что в наследовании родительский класс ничего не знает о своих дочерних классах. Поэтому, когда я сам использую родительский класс, я не использую его дочерние классы, верно? – laukok

+0

Родительскому классу не нужно ничего знать о детях, оно автоматическое. Они наследуют методы родителя. – Barmar

+0

ok. поэтому, если я 'ожидаю' SimpleBook только, как бы я' также принимаю' BookExtension? они фактически «независимы» (от cos BookExtension зависит от SimpleBook, так же как BookAdapter зависит от SimpleBook). – laukok