首頁  >  文章  >  後端開發  >  物件導向-設計模式:適配器模式

物件導向-設計模式:適配器模式

巴扎黑
巴扎黑原創
2017-05-20 14:35:181820瀏覽

什麼是適配器模式?

適配器模式只是將某個物件的介面適配為另一個物件所期望的介面。

適配器模式應用問題與解決方案

在應用程式中,您也許會使用一個在體系結構上可靠且穩定的工作程式碼庫。不過我們常常會增加新的功能,這些功能要求採用不同的方式使用現有的對象,而不是採用原先設計的方式。此時,障礙可能只是新功能需要一個不同的名字。在較為複雜的場景中,障礙也可能是新功能需要與原始物件稍有不同的行為。

針對上述問題,我們採用的解決方案是使用適配器模式建立另一個物件。這個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類別就可以了。

適應新類別

有了適配器後,擴充也變得更容易了。

繼續以上的例子,在支付寶的基礎上,我們再增加微信支付,它與支付寶的支付方式不同,必須透過掃碼才能支付。

這種情況也應該使用適配器,而不是直接使用微信的支付功能。

程式碼如下:

/** 
 * 微信支付类 
 */  
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如下:

物件導向-設計模式:適配器模式

大的應用程式都會不斷地加入新函式庫和新API。

為避免它們的變更引發問題,應該用適配器模式包裝起來,提供應用統一的引用方式。

它會讓我們的程式碼更有結構化,方便管理和擴充。

以上是物件導向-設計模式:適配器模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn