【问题标题】:PHP design patterns - inheritance vs adapter pattern?PHP 设计模式 - 继承与适配器模式?
【发布时间】:2014-12-23 05:13:56
【问题描述】:

我对适配器模式的概念有点困惑。我发现适配器类与我通常编写的扩展类非常相似。那么,它们之间究竟有什么区别

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


      }

第二种解决方案似乎要简单得多。那么它(以及一般的其他继承类)是否被视为适配器类?

【问题讨论】:

    标签: php inheritance design-patterns adapter extends


    【解决方案1】:

    区别在于类如何与多态一起使用。

    如果您使用继承,任何需要SimpleBook 的函数也将接受BookExtension,或任何其他扩展SimpleBook 的类。例如,如果您有:

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

    您可以在 BookExtension 上调用此函数,因为它继承了 SimpleBook::getTitle() 方法。

    请注意,反之亦然:期望BookExtension 的函数将无法与SimpleBook 一起使用。例如,如果函数调用getAuthorAndTitle(),如果参数是SimpleBook,则该函数将失败,因为那里没有这样的方法。

    如果使用适配器,这两个类是独立的。期望 SimpleBook 的函数将不接受 BookAdapter,反之亦然。您不能在 BookAdapter 上调用 PigLatinTitle(),因为没有 BookAdapter::getTitle() 方法。

    您可以通过向BookAdapter 添加一个__call() 魔术方法,然后在$this->book 上重新调用该方法,使适配器像继承一样工作:

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

    【讨论】:

    • 感谢您的回答。我对If you use inheritance, any function that expects a SimpleBook will also accept a BookExtension, or any other class that extends SimpleBook. 有点困惑,我认为在继承中,父类对其子类一无所知。所以当我自己使用父类时,我并没有使用它的子类,对吧?
    • 父类不需要知道孩子的任何事情,它是自动的。它们继承父级的方法。
    • 好的。所以如果我只expect SimpleBook,我将如何also accept BookExtension?它们实际上是independent(因为 BookExtension 依赖于 SimpleBook,就像 BookAdapter 依赖于 SimpleBook)。
    • 查看我添加的示例。
    • 两者都没有,只是一个普通的函数。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-09-04
      • 1970-01-01
      • 2011-01-19
      • 2017-08-01
      • 2020-09-10
      • 2016-09-05
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多