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