2

I am a bit confused with the concept of adapter pattern. I find that adapter classes are very similar to extended classes that I would write usually. So, what is the differences between them actually?

For instance (an example from this 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();
        }


      }

The second solution seems a lot simpler. So is it (and other inheritance classes in general) considered as adapter class then?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
Run
  • 54,938
  • 169
  • 450
  • 748

2 Answers2

1

The difference relates to how the classes can be used with polymorphism.

If you use inheritance, any function that expects a SimpleBook will also accept a BookExtension, or any other class that extends SimpleBook. For instance, if you had:

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

you can call this function on a BookExtension because it inherits the SimpleBook::getTitle() method.

Note that it doesn't work the other way around: a function that expects BookExtension won't work with SimpleBook. For instance, if the function calls getAuthorAndTitle(), that will fail if the argument is a SimpleBook because there's no such method there.

If you use the adapter, the two classes are independent. Functions that expect a SimpleBook will not accept a BookAdapter, and vice versa. You could not call PigLatinTitle() on a BookAdapter, because there's no BookAdapter::getTitle() method.

You can make the adapter work like inheritance by adding a __call() magic method to BookAdapter, and then re-calling the method on $this->book:

public function __call($name, $arguments) {
    return call_user_func_array(array($this->book, $name), $arguments);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks for the answer. I am a bit confused with `If you use inheritance, any function that expects a SimpleBook will also accept a BookExtension, or any other class that extends SimpleBook.` I thought in inheritance, the parent class does not know anything about its children classes. So when I use the parent class on its own, I am not using its children classes, right? – Run Dec 23 '14 at 05:36
  • The parent class doesn't need to know anything about the children, it's automatic. They inherit the parent's methods. – Barmar Dec 23 '14 at 05:37
  • ok. so if I `expect` SimpleBook only, how would I `also accept` BookExtension? they are actually `independent` (of cos BookExtension depends on SimpleBook, just as BookAdapter depends on SimpleBook). – Run Dec 23 '14 at 05:42
  • 1
    See the example I added. – Barmar Dec 23 '14 at 05:43
  • sorry I can understand about the adapter you try explain. not sure about the inheritance though... where do you place this `PigLatineTitle`? in `SimpleBook` or in `BookExtension`? – Run Dec 23 '14 at 05:55
  • 1
    It's not in either of them, it's just an ordinary function. – Barmar Dec 23 '14 at 05:56
1

You can read this interesting question about adapter. Most likely its a wrapper pattern with inner and outer class:How do the Proxy, Decorator, Adapter, and Bridge Patterns differ?.

Community
  • 1
  • 1
Micromega
  • 12,486
  • 7
  • 35
  • 72