简体   繁体   English

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

[英]PHP design patterns - inheritance vs adapter pattern?

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, 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 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, 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? 那么,它(以及其他继承类)是否被视为适配器类?

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? 最有可能是带有内部和外部类的包装器模式: 代理,装饰器,适配器和桥接器模式有何不同? .

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 . 如果使用继承,则任何期望SimpleBook函数也将接受BookExtension或扩展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. 您可以在BookExtension上调用此函数,因为它继承了SimpleBook::getTitle()方法。

Note that it doesn't work the other way around: a function that expects BookExtension won't work with SimpleBook . 请注意,它不会BookExtension起作用:期望BookExtension的函数不能与SimpleBook一起SimpleBook For instance, if the function calls getAuthorAndTitle() , that will fail if the argument is a SimpleBook because there's no such method there. 例如,如果函数调用getAuthorAndTitle() ,则在参数为SimpleBook将失败,因为那里没有此类方法。

If you use the adapter, the two classes are independent. 如果使用适配器,则这两个类是独立的。 Functions that expect a SimpleBook will not accept a BookAdapter , and vice versa. 期望SimpleBook函数将不接受BookAdapter ,反之亦然。 You could not call PigLatinTitle() on a BookAdapter , because there's no BookAdapter::getTitle() method. 您不能在BookAdapter上调用PigLatinTitle() ,因为没有BookAdapter::getTitle()方法。

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 : 通过将__call()魔术方法添加到BookAdapter ,然后在$this->book上重新调用该方法,可以使适配器像继承一样工作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM