适配器模式(Adapter / Wrapper)就是为了将已存在的东西(接口)转换成适合我们需要、能被我们所利用的东西。在现实生活中,适配器更多的是作为一个中间层来实现这种转换作用。比如电源适配器,它是用于电流变换(整流)的设备。
【一】模式定义
首先我们来看看什么是适配器。
适配器的存在,就是为了将已存在的东西(接口)转换成适合我们需要、能被我们所利用的东西。在现实生活中,适配器更多的是作为一个中间层来实现这种转换作用。比如电源适配器,它是用于电流变换(整流)的设备。
适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
【二】UML类图
【三】示例代码
PaperBookInterface.php
<?php namespace DesignPatterns\Structural\Adapter; /** * PaperBookInterface 是纸质书接口 */ interface PaperBookInterface { /** * 翻页方法 * * @return mixed */ public function turnPage(); /** * 打开书的方法 * * @return mixed */ public function open(); }
Book.php
<?php namespace DesignPatterns\Structural\Adapter; /** * Book 是纸质书实现类 */ class Book implements PaperBookInterface { /** * {@inheritdoc} */ public function open() { } /** * {@inheritdoc} */ public function turnPage() { } }
EBookAdapter.php
<?php namespace DesignPatterns\Structural\Adapter; /** * EBookAdapter 是电子书适配器类 * * 该适配器实现了 PaperBookInterface 接口, * 但是你不必修改客户端使用纸质书的代码 */ class EBookAdapter implements PaperBookInterface { /** * @var EBookInterface */ protected $eBook; /** * 注意该构造函数注入了电子书接口EBookInterface * * @param EBookInterface $ebook */ public function __construct(EBookInterface $ebook) { $this->eBook = $ebook; } /** * 电子书将纸质书接口方法转换为电子书对应方法 */ public function open() { $this->eBook->pressStart(); } /** * 纸质书翻页转化为电子书翻页 */ public function turnPage() { $this->eBook->pressNext(); } }
EBookInterface.php
<?php namespace DesignPatterns\Structural\Adapter; /** * EBookInterface 是电子书接口 */ interface EBookInterface { /** * 电子书翻页 * * @return mixed */ public function pressNext(); /** * 打开电子书 * * @return mixed */ public function pressStart(); }
Kindle.php
<?php namespace DesignPatterns\Structural\Adapter; /** * Kindle 是电子书实现类 */ class Kindle implements EBookInterface { /** * {@inheritdoc} */ public function pressNext() { } /** * {@inheritdoc} */ public function pressStart() { } }
【四】测试代码
Tests/AdapterTest.php
<?php namespace DesignPatterns\Structural\Adapter\Tests; use DesignPatterns\Structural\Adapter\EBookAdapter; use DesignPatterns\Structural\Adapter\Kindle; use DesignPatterns\Structural\Adapter\PaperBookInterface; use DesignPatterns\Structural\Adapter\Book; /** * AdapterTest 用于测试适配器模式 */ class AdapterTest extends \PHPUnit_Framework_TestCase { /** * @return array */ public function getBook() { return array( array(new Book()), // 我们在适配器中引入了电子书 array(new EBookAdapter(new Kindle())) ); } /** * 客户端只知道有纸质书,实际上第二本书是电子书, * 但是对客户来说代码一致,不需要做任何改动 * * @param PaperBookInterface $book * * @dataProvider getBook */ public function testIAmAnOldClient(PaperBookInterface $book) { $this->assertTrue(method_exists($book, 'open')); $this->assertTrue(method_exists($book, 'turnPage')); } }
登录后可发表评论