0

0

面向对象进阶-设计模式:适配器模式

巴扎黑

巴扎黑

发布时间:2017-05-20 14:35:18

|

2070人浏览过

|

来源于php中文网

原创

什么是适配器模式?

适配器模式只是将某个对象的接口适配为另一个对象所期望的接口。

适配器模式应用问题与解决方案

在应用程序中,您也许会使用一个在体系结构上可靠稳定的工作代码库。不过我们常常会添加新的功能,这些功能要求采用不同的方式使用现有的对象,而不是采用原先设计的方式。此时,障碍可能只是新功能需要一个不同的名字。在较为复杂的场景中,障碍也可能是新功能需要与原始对象稍有不同的行为。

针对上述问题,我们采用的解决方案是使用适配器模式构建另一个对象。这个Adapter对象充当了原始应用与新功能之间的中介。适配器模式为已有的对象定义了新的接口,从而能够匹配新对象的要求。

问题

假设支付宝支付类的功能如下:

/** 
 * 支付宝支付类 
 */  
class Alipay  
{  
    public function sendPayment()  
    {  
        echo '使用支付宝支付。';  
    }  
}  
  
// 客户端代码  
$alipay = new Alipay();  
$alipay->sendPayment();

我们直接实例化Alipay类完成支付功能,这样的客户端代码可能很多。

一段时间后,如果支付宝的Alipay类升级,方法名由sendPayment()变成goPayment()会怎样?

所有用了sendPayment()的客户端代码都要改变。

如果Alipay类频繁升级,或者客户端在很多地方使用,这会是极大的工作量。

解决

现在我们用适配器模式来解决。

我们在客户端和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类就可以了。

迷你天猫商城
迷你天猫商城

迷你天猫商城是一个基于Spring Boot的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程:用户从注册开始,到完成登录,浏览商品,加入购物车,进行下单,确认收货,评价等一系列操作。 作为迷你天猫商城的核心组成部分之一,天猫数据管理后台包含商品管理,订单管理,类别管理,用户管理和交易额统计等模块,实现了对整个商城的一站式管理和维护。所有页面均兼容IE10及以上现代浏览器。部署方式1、项目

下载

适配新类

有了适配器后,扩展也变得更容易了。

继续以上的例子,在支付宝的基础上,我们再增加微信支付,它与支付宝的支付方式不同,必须通过扫码才能支付。

这种情况也应该使用适配器,而不是直接使用微信的支付功能。

代码如下:

/** 
 * 微信支付类 
 */  
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有变化,我们仅需修改客户端依赖的适配器类就可以,不用修改、暴露第三方类本身。

UML图

以上适配器模式的代码对应UML如下:

1.png

总结

大的应用都会不断地加入新库和新API。

为避免它们的变更引发问题,应该用适配器模式包装起来,提供应用统一的引用方式。

它会让我们的代码更具结构化,便于管理和扩展。

相关专题

更多
vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

26

2025.12.30

金山文档相关教程
金山文档相关教程

本专题整合了金山文档相关教程,阅读专题下面的文章了解更多详细操作。

28

2025.12.30

PS反选快捷键
PS反选快捷键

本专题整合了ps反选快捷键介绍,阅读下面的文章找到答案。

25

2025.12.30

表格中一行两行的方法
表格中一行两行的方法

本专题整合了表格中一行两行的相关教程,阅读专题下面的文章了解更多详细内容。

3

2025.12.30

cpu温度过高解决方法大全
cpu温度过高解决方法大全

本专题整合了cpu温度过高相关教程,阅读专题下面的文章了解更多详细内容。

5

2025.12.30

ASCII码介绍
ASCII码介绍

本专题整合了ASCII码相关内容,阅读专题下面的文章了解更多详细内容。

31

2025.12.30

GPS是什么
GPS是什么

本专题整合了GPS相关内容,阅读专题下面的文章了解更多详细内容。

3

2025.12.30

wifi拒绝接入
wifi拒绝接入

本专题整合了wifi拒绝接入相关教程,阅读下面的文章了解更多详细方法。

9

2025.12.30

丰网速运介绍
丰网速运介绍

本专题整合了丰网速运查询入口以及相关内容,阅读专题下面的文章了解更多内容。

3

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.1万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.3万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 1.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号