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
)允許類協同工作,否則由於介面不兼容而無法正常工作。