php 适配器模式
适配器模式,即根据客户端需要,将某个类的接口转换成特定样式的接口,以解决类之间的兼容问题。
如果我们的代码依赖一些外部的API,或者依赖一些可能会经常更改的类,那么应该考虑用适配器模式。
下面我们以集成支付宝支付功能为例。
1 问题
假设支付宝支付类的功能如下:
/**
* 支付宝支付类
*/
class Alipay
{
public function sendPayment()
{
echo '使用支付宝支付。';
}
}
// 客户端代码
$alipay = new Alipay();
$alipay->sendPayment();
我们直接实例化Alipay
类完成支付功能,这样的客户端代码可能很多。
一段时间后,如果支付宝的Alipay
类升级,方法名由sendPayment()
变成goPayment()
会怎样?
所有用了sendPayment()
的客户端代码都要改变。
如果Alipay
类频繁升级,或者客户端在很多地方使用,这会是极大的工作量。
2 解决
现在我们用适配器模式来解决。
我们在客户端和Alipay
类之间加一个中间类,也就是适配器类,转换原始的Alipay
为客户端需要的形式。
为让客户端能调用到统一的类方法,我们先定义一个适配器接口:
/**
* 适配器接口,所有的支付适配器都需实现这个接口。
* 不管第三方支付实现方式如何,对于客户端来说,都
* 用pay()方法完成支付
*/
interface PayAdapter
{
public function pay();
}
因为Alipay
类我们无法控制,而且它有可能经常更新,所以我们不对它做任何修改。
我们新建一个AlipayAdapter
适配器类,在pay()
中转换Alipay
的支付功能,如下:
/**
* 支付宝适配器
*/
class AlipayAdapter implements PayAdapter
{
public function pay()
{
// 实例化Alipay类,并用Alipay的方法实现支付
$alipay = new Alipay();
$alipay->sendPayment();
}
}
客户端使用方式:
// 客户端代码
$alipay = new AlipayAdapter();
// 用pay()方法实现支付
$alipay->pay();
这样,当Alipay
的支付方法改变,只需要修改AlipayAdapter
类就可以了。
3 适配新类
有了适配器后,扩展也变得更容易了。
继续以上的例子,在支付宝的基础上,我们再增加微信支付,它与支付宝的支付方式不同,必须通过扫码才能支付。
这种情况也应该使用适配器,而不是直接使用微信的支付功能。
代码如下:
/**
* 微信支付类
*/
class WechatPay
{
public function scan()
{
echo '扫描二维码后,';
}
public function doPay()
{
echo '使用微信支付';
}
}
/**
* 微信支付适配器
*/
class WechatPayAdapter implements PayAdapter
{
public function pay()
{
// 实例化WechatPay类,并用WechatPay的方法实现支付。
// 注意,微信支付的方式和支付宝的支付方式不一样,但是
// 适配之后,他们都能用pay()来实现支付功能。
$wechatPay = new WechatPay();
$wechatPay->scan();
$wechatPay->doPay();
}
}
客户端使用:
// 客户端代码
$wechat = new WechatPayAdapter();
// 也是用pay()方法实现支付
$wechat->pay();
这就是适配器的扩展特性。
我们创建了一个用于处理第三方类(支付宝、微信支付)的方法,
如果它们的API有变化,我们仅需修改客户端依赖的适配器类就可以,不用修改、暴露第三方类本身。
4 UML图
以上适配器模式的代码对应UML如下:
注意:适配器模式中,适配器类的名称和创建方式一定是不会频繁改动的。
对于客户端来说,引用适配器类的方式应该是统一而不变的,这才算是正确使用适配器。
5 总结
大的应用都会不断地加入新库和新API。
为避免它们的变更引发问题,应该用适配器模式包装起来,提供应用统一的引用方式。
它会让我们的代码更具结构化,便于管理和扩展。
相关文章
- php和asp网络验证码,Verifycode 1个简单的网页图片验证码的示例程序,基本上现有 字和字母都可以识别。 WEB(ASP,PHP,…) 238万源代码下载- www.pudn.com…
- 21-物联网开发终端管理篇-安装PHP,测试GET,POST接口(linux系统,宝塔)
- 【说站】php上传文件代码
- php-检查网站是否宕机
- PHP JWT简易使用
- [PHP] apache在worker模式配置fastcgi使用php-fpm详解编程语言
- [PHP] 编译构建最新版PHP源码详解编程语言
- 使用Redis集群提升PHP性能(redis集群php)
- 探索Linux下查看PHP扩展的奥秘(linux查看php扩展)
- 常用php操作redis命令整理(四)SET类型详解编程语言
- PHP设计模式_注册树模式详解编程语言
- win7 安装php插件imagick详解编程语言
- Linux下运行PHP脚本的简单步骤(linux运行php脚本)
- 环境搭建PHP在Linux下的环境搭建与应用(php用linux)
- PHP操作MySQL数据库,实现强大的数据功能(php调用mysql数据库)
- 7.4Linux 发布 PHP 7.4 平台更新(linux发布php)
- Centos编译安装 LAMP (apache-2.4.7 + mysql-5.5.35 + php 5.4.8)
- 利用Redis和PHP实现高效数据处理(redis php 使用)
- PHP 5.5 环境下安装 MS SQL驱动连接(php5.5装mssql)
- PHP图片上传至MySQL:实现快速可靠的数据存储(php图片上传mysql)
- 使用Redis需要PHP版本满足特定要求(redis需要php版本)
- 使用PHP连接Redis应用的指南(redis连接 php)
- IIS+PHP+MySQL+Zend配置(视频教程)
- php表单验证实现代码
- php开启安全模式后禁用的函数集合
- PHP学习笔记IIS7下安装配置php环境
- php数组的概述及分类与声明代码演示
- 一个简洁的PHP可逆加密函数(分享)
- 调整PHP的性能
- PHP获取php,mysql,apche的版本信息示例代码
- thinkphp文件处理类Dir.class.php的用法分析
- 图解找出PHP配置文件php.ini的路径的方法