PHP设计模式 - 继承与适配器模式?

时间:2014-12-23 05:13:56

标签: php inheritance design-patterns adapter extends

我对适配器模式的概念有点困惑。我发现适配器类与我通常编写的扩展类非常相似。那么,它们之间的差异实际上是什么?

例如(来自此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();
        }


      }

第二种解决方案似乎更简单。那么它(和其他继承类一般)被视为适配器类呢?

2 个答案:

答案 0 :(得分:1)

您可以阅读有关适配器的这个有趣问题。很可能它是一个包含内部和外部类的包装模式:How do the Proxy, Decorator, Adapter, and Bridge Patterns differ?

答案 1 :(得分: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);
}