快捷搜索:

php设计模式介绍之适配器模式

接口的改变,是一个必要法度榜样员们必须(虽然很不甘愿宁肯)吸收和处置惩罚的普遍问题。法度榜样供给者们改动 他们的代码;系统库被修正;各类法度榜样说话以及相关库的成长和进化。我孩子的无数玩具中有一个简要地 描述了这个两难场所场面:你无法合理安排一个不得其所的人。

问题

你若何避免因外部库的 API改变而带来的不便?要是你写了一个库,你能否供给一种措施容许你软件的现有用户进行完美地进级 ,纵然你已经改变了你的API?为了更好地合适于你的必要,你应该若何改变一个工具的接口?

办理规划

适配器(Adapter)模式为工具供给了一种完全不合的接口。你可以运用适配器(Adapter) 来实现一个不合的类的常见接口,同时避免了因进级和拆解客户代码所引起的胶葛。

斟酌一下 当(不是假设!)一个第三方库的API改变将会发生什么。以前你只能是咬紧牙关改动所有的客户代码,而 环境每每还不那么简单。你可能正从事一项新的项目,它要用到新版本的库所带来的特点,但你已经拥 有许多旧的利用法度榜样,并且它们与曩昔旧版本的库交互运行地很好。你将无法证实这些新特点的使用价 值,假如此次进级意味着将要涉及到其它利用法度榜样的客户代码。

注:节制体模式

适配器 (Adapter)模式是节制体模式的最新典型。一个适配器(Adapter)的布局类似于代理办事器(Proxy)和修饰 器(Decorator),而它们的不合之处在于,适配器(Adapter)的目的是改变封装类的接口,代理办事器 (Proxy)和修饰器(Decorator)则是维持接口不变。

样本代码

让我们看看当API改变时,如 何保护利用法度榜样不受影响。

假设你费尽心思探求相宜的库,着末终于找到了HwLib,一个(假设的 )被设计用来发送信息的代码集。

下面是HwLib类的源代码:

// PHP4

/**

* the HwLib helps programmers everywhere write their first program

* @package HelloWorld

* @version 1

*/

class HwLib {

/**

* Say “Hello”

* @deprec this function is going away in the future

* @return string

*/

function hello() {

return ‘Hello ‘;

}

/**

* target audience

* @return string

*/

function world() {

return ‘World!’;

}

}

下面是库运行的典型:

$hw =& new HwLib;

echo $hw->hello(), $hw->world();

HwLib有完整的阐明文档 。在文档中作者已经明确指出hello()措施会在未来的版本中不被支持(以致淘汰)。

接下来,现 在假设第二版的HwLib已经宣布。一个全新的greet()措施代替了hello()。

下面是这个库的新版 本(注释已被抽取掉落):

// version 2

class HwLib {

function greet() {

return ‘Greetings and Salutations ‘;

}

function world() {

return ‘World!’;

}

}

为了适应HwLib的不合版本进行编码, 先辈行一些基于初版本HwLib接口的测试:

class AdapterTestCase extends UnitTestCase {

function TestOriginalApp() {

$lib =& new HwLib;

$this- >assertEqual(

‘Hello World!’

,$lib->hello().$lib->world ());

}

}

你同样可以注解,对这个库的简单进级将造成此利用法度榜样的掉效。

class AdapterTestCase extends UnitTestCase {

The Adapter Pattern 221

function TestOriginalAppWouldFail() {

$lib =& new HwLib; // now using HwLib version 2

$this->assertFalse(method_exists($lib, ‘hello’));

}

}

您可能还会对下面的文章感兴趣: