加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP设计模式之适配器模式定义与用法详解

发布时间:2020-12-12 22:27:38 所属栏目:PHP教程 来源:网络整理
导读:本篇章节讲解PHP设计模式之适配器模式定义与用法。供大家参考研究具体如下: 适配器很容易理解,大多数人家庭都有手机转接器,用来为移动电话充电,这就是一种适配器. 如果只有USB接头,就无法将移动电话插到标准插座上. 实际上,必须使用一个适配器,一

本篇章节讲解PHP设计模式之适配器模式定义与用法。分享给大家供大家参考,具体如下:

适配器很容易理解,大多数人家庭都有手机转接器,用来为移动电话充电,这就是一种适配器. 如果只有USB接头,就无法将移动电话插到标准插座上. 实际上,必须使用一个适配器,一端接USB插头,一端接插座. 当然,你可以拿出电气工具,改装USB连接头,或者重新安装插座,不过这样会带来很多额外的工作,而且可能会把连接头或插座弄坏. 所以,最可取的方法就是找一个适配器. 软件开发也是如此.

类适配器模式(使用继承)

类适配器模式很简单,不过与对象适配器模式相比,类适配器模式的灵活性弱些,类适配器简单的原因在于,适配器(Adapter)会从被适配者(Adaptee)继承功能,所以适配模式中需要编写的代码比较少.

由于类适配器模式包含双重继承,但是PHP并不支持双重继承,不过幸运的是,PHP可以用接口来模拟双重继承,下面是一个正确的结构,不仅继承了一个类,同时还继承了一个接口

实现类适配器模式时,参与者必须包括一个PHP接口

下面以一个货币兑换为例来演示:

假设有一个企业网站在同时销售软件服务和软件产品,目前,所有交易都在美国进行,所以完全可以用美元来完成所有计算.现在开发人员希望能有一个转换器能处理美元和欧元的兑换,而不改变原来按美元交易额的类.通过增加一个适配器,现在程序即可以用美元计算也可以用欧元计算.

DollarCalc.php

product = $productNow; $this->service = $serviceNow; $this->dollar = $this->product + $this->service; return $this->requestTotal(); } public function requestTotal() { $this->dollar *= $this->rate; return $this->dollar; } }

查看这个类,可以看到其中有一个属性$rate,requestTotal()方法使用$rate计算一次交易的金额.在这个版本中,这个值设置为1,实际上总金额无需再乖以兑换率,不过如果要为客户提供折扣或者要增加额外服务或产品的附加费,$rate变量会很方便. 这个类并不是适合器模式的一部分,不过这是一个起点.

需求变化了

现在客户的公司要向欧洲发展,所以需要开发一个应用,能够用欧元完成同样的计算. 你希望这个欧元计算能够像DollarCalc一样,所要做的就是改变变量名.

EuroCalc.php

product = $productNow; $this->service = $serviceNow; $this->euro = $this->product + $this->service; return $this->requestTotal(); } public function requestTotal() { $this->euro *= $this->rate; return $this->euro; } }

接下来,再把应用的其余部分插入到EuroCalc类中. 不过,因为客户的所有数据都是按美元计算的.换句话说,如果不重新开发整个程序,就无法在系统中"插入"这个欧元计算. 但是你不想这么做. 为了加入EuroCalc,你需要一个适配器: 就像找一个适配器来适应欧洲的插座一样,可以创建一个适配器,使你的系统能够使用欧元. 幸运的是,类适配器正是为这样的情况设计的.首先需要创建一个接口. 在这个类图中,这个接口名为ITarget. 它只有一个方法requester(). requester()是一个抽象方法,要由接口的具体实现来实现这个方法.

ITarget.php

现在开发人员可以实现requester()方法,请求欧元而不是美元.

在使用继承的适配器设计模式中,适配器(Adapter)参与都既实现ITarget接口,还实现了具体类EuroCalc. 创建EuroAdapter不需要做太多工作,因为大部分工作已经在EuroCal类中完成.现在要做的就是实现request()方法,使它能把美元值转换为欧元值.

EuroAdapter.php

requester(); } public function requester() { $this->rate = 0.8111; return $this->rate; } }

类适配模式中,一个具体类会继承另一个具体类,有这种结构的设计模式很少见,大多数设计模式中,几乎都是继承一个抽象类,并由类根据需要实现其抽象方法和属性. 换句话说,一般谈到继承时,都是具体类继承抽象类.

由于既实现了一个接口又扩展了一个类,所以EuroAdapter类同时拥有该接口和具体类的接口. 通过使用requester()方法,EuroAdapter类可以设置rate值(兑换率),从而能使用被适配者的功能,而元而做任何改变.

下面定义一个Client类,从EuroAdapter和DollarCalc类发出请求. 可以看到,原来的DollarCalc仍能很好地工作,不过它没有ITarget接口.

Client.php