PHP设计模式——适配器模式
- 2019 年 11 月 24 日
- 筆記
将类的接口转换为客户端期望的另一个接口。因为接口不兼容,无法一起工作,而适配器可以使类可以一起工作。
如今,全球共有15种电源插座插头在使用。从中国到新加坡旅行时,如果没有插座适配器,可能会遇到麻烦。前往新加坡参加研讨会的Marina非常沮丧,因为她意识到由于插头和插座不匹配,无法在酒店房间给手机和配件充电。她去了接待区,问旅馆工作人员是否有适配器。旅馆的工作人员很有礼貌,但是他们告诉她没有这种适配器,而Marina必须从当地的硬件那里购买一个。
在新加坡,使用的插座插头为G型,而来自中国的电子设备则使用A型插头。G型插座接口与A型插头不兼容,后者需要A型插座接口。在这种情况下,我们需要使用G型适配器来连接A型适配器。
这是适配器模式(Adapter Pattern
)的示例。让我们看看它在代码中的样子。
首先,我们有一个TypeAPlug
类和一个TypeGSocket
类:
class TypeAPlug { public function connect(TypeASocketInterface $socket) { $socket->connectTwoPins(); } } class TypeGSocket { public function connectThreePins() {} }
如我们所见,TypeAPlug
类的connect()
方法期望使用TypeASocketInterface
类型,并调用TypeASocketInterface
类型的方法connectTwoPins()
。我们需要创建一个G
型套接字接口来连接A
型套接字接口适配器。我们将其命名为GtypeToAtypeSocketAdatper
:
class GtypeToAtypeSocketAdatper implements TypeASocketInterface { private $typeGSocket = null; public function __construct(TypeGSocket $typeGSocket) { $this->typeGSocket = $typeGSocket; } public function connectTwoPins() { // 使用一些算法 $this->connectThreePins(); } }
GtypeToAtypeSocketAdatper
类实现TypeASocetInterface
接口,并且在实例化时接受TypeGSocket
类。此处使用的有利于合成的技术与“装饰器模式”中的类似。关键区别在于装饰器模式保留其包装的类的类类型。但是,适配器模式将其包装的类的类类型更改为一个客户端期望的类。
最后,让我们看看G
型插座是如何转换为A
型插座并由A
型插头使用的:
$typeAPlug = new TypeAPlug(); $typeGSocket = new TypeGSocket(); $gTypeToAtypeAdapter = new GtypeToAtypeSocketAdatper($typeGSocket); $typeAPlug->connect($gTypeToAtypeAdapter);
在适配器模式中,有一些组件可帮助您熟悉该模式,如下:
- Adaptee:这是在引入适配器类之前存在的类。在我们的例子中,它将是
TypeGSocket
类。 - Adapter:这是一个类,它包装一个
Adaptee
类并使其与客户端类所期望的兼容。此类将适配器类与客户端类分离。在我们的例子中,它是GtypeToAtypeSocketAdatper
类。 - Client:这是向适配器发出请求并接收其期望值的类。它不知道适配器类的存在。在我们的例子中,它是
TypeAPlug
类。
在我们的示例中,适配器模式(Adapter Pattern
)将类(TypeGSockt
类)的接口转换为客户端(TypeAPlug
)期望的另一个接口(TypeAPlugInterface
接口)。适配器(GtypeToAtypeSocketAdatper
)允许类协同工作,否则由于接口不兼容而无法正常工作。