我有点混淆了适配器模式的概念。我发现适配器类与我通常编写的扩展类非常相似。那么,它们之间的差异实际上是什么呢?
例如(这个链接中的一个例子),
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();
}
}第二个解决方案似乎要简单得多。那么,它(以及一般的其他继承类)是否被认为是适配器类?
发布于 2014-12-23 05:24:56
不同之处在于如何使用这些类进行多态性。
如果使用继承,任何期望使用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);
}发布于 2014-12-23 06:35:04
您可以阅读有关适配器的这个有趣的问题。它很可能是一个包含内部和外部类的包装模式:代理、装饰器、适配器和桥模式有何不同?。
https://stackoverflow.com/questions/27614438
复制相似问题