
适配器模式Adapter的作用是将一个类的接口转换成客户希望的另外一个接口,使用原本不兼容的而不能在一起工作的那些类可以在一起工作,用好此模式可以使程序易于扩展,当你的代码依赖于一些外部的API时可以尝试使用适配器模式,适配器模式同样也适用于某些变动频繁的类,废话不多说,以一个支付api的例子来看一下:
未使用适配器
Alipay
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace App;
class Alipay
{
public function __construct() {
// ...
}
public function sendPayment($amount) {
echo "支付宝付款: ". $amount;
}
}
|
Wxpay
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace App;
class Wxpay
{
public function __construct() {
// ...
}
public function doPayment($amount) {
echo "微信支付: ". $amount;
}
}
|
客户端调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<?php
namespace App;
class ClientOld
{
public function alipay()
{
$alipay = new Alipay();
$alipay->sendPayment(100);
}
public function wxpay()
{
$alipay = new Wxpay();
$alipay->doPayment(100);
}
}
|
使用适配器后
PayAdapter
1
2
3
4
5
6
|
<?php
namespace App;
interface PayAdapter{
public function pay($amount);
}
|
Alipay
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace App;
class Alipay
{
public function __construct() {
// ...
}
public function sendPayment($amount) {
echo "支付宝付款: ". $amount;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
namespace App;
class AlipayAdapter implements PayAdapter{
private $alipay;
public function __construct(Alipay $alipay) {
$this->alipay = $alipay;
}
public function pay($amount) {
$this->alipay->sendPayment($amount);
}
}
|
Wxpay
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace App;
class Wxpay
{
public function __construct() {
// ...
}
public function doPayment($amount) {
echo "微信支付: ". $amount;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
namespace App;
class WxpayAdapter implements PayAdapter{
private $wxpay;
public function __construct(Wxpay $wxpay) {
$this->wxpay = $wxpay;
}
public function pay($amount) {
$this->wxpay->doPayment($amount);
}
}
|
CashPay
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php
namespace App;
class CashPay
{
public function __construct() {
// ...
}
public function pay($amount) {
echo "现金支付: ". $amount;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
namespace App;
class CashPayAdapter implements PayAdapter{
private $cash;
public function __construct(CashPay $cash) {
$this->cash = $cash;
}
public function pay($amount) {
$this->cash->pay($amount);
}
}
|
客户端调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php
namespace App;
class Client {
public function alipay(){
$alipay = new AlipayAdapter(new Alipay());
$alipay->pay(100);
}
public function wxpay(){
$alipay = new WxpayAdapter(new Wxpay());
$alipay->pay(100);
}
public function cash(){
$alipay = new CashPayAdapter(new CashPay());
$alipay->pay(100);
}
}
|
简单解释一下,当我们做一些调用第三方API时会用到对方提供的SDK,而对方的SDK有时会有改动,比如支付宝支付的接口中付款的方法以前叫sendPayment,后来又改成sendPay,如果我们不使用上面的适配器模式的话,如果系统中有多处调用支付类需要改动很多,而使用适配模式后只需要更改AlipayAdapter里的pay方法即可,不需要暴露其外部接口,而且在增加新的支付平台时只需增加对应的Adapter适配类做转化即可。
适配器模式使用场景还是非常多的,比如数据库操作类的封装、缓存类的封装、日志类的封装都可以使用适配器模式,另外像我们做旅游电商平台的经常需要对接美团、携程、有赞、飞猪、去哪儿等OTA平台,这些平台的接口有的更新比较频繁,而且部分平台提供的SDK里命名也比较混乱,不能做到平滑升级,如果一开始就使用适配器模式去对接,后续不管怎么改都只需要改对接的适配器类,业务代码一行也不需要更改。
参考资料
觉得本文对你有用请点右下角“再看”,也欢迎转发,如对文中观点有不同看法欢迎评论留言。