適配器模式 Adapter Pattern
先看一種簡單的理解:
將各種截然不同的函數接口封裝成統一的API。比如, PHP
中可以操作主流的數據庫, 比如MySQL
/Oracle
/SQLSERVER
,可以用適配器模式統一成一致的API
; 還有緩存(cache
)適配器,可以將memcache
/redis
/file
/apc
等不同的緩存調用方法統一。 定義一個接口(有幾個方法,以及相應的參數)。然後,有幾種不同的情況,就寫幾個類實現該接口。
這個是比較容易理解的. 那我們主要看第二種理解方式.
適配器模式, 就是將一個類的接口, 轉換成客戶期望的另一個類的接口, 以便讓原本不兼容的一些類可以對外提供一個統一的訪問api.
適配器中的主要角色
- 目標(
Target
): 定義客戶端使用的與特定領域相關的接口, 這也就是我們所期待得到的 - 源(
Adaptee
): 需要進行適配的接口 - 適配器(
Adapter
): 對Adaptee
的接口與Target接口進行適配. 適配器是該模式的核心, 適配器把源接口(Adaptee
)轉成成目標接口(Target
), 此角色爲具體類.
比如, 我國的民用電是220v50Hz(Adaptee
), 但是手機充電需要直流5V(Target
), 這時你就需要一個電源適配器(Adapter
)來進行轉換; , 電源適配器一般是標準的USB接口(Adaptee
), 而手機現在主要使用Type-c
和Lighting
接口(Target
), 這時你就需要一個合適的數據線(Adapter
)來適配不同的手機接口.
類適配器模式
類適配器使用的是繼承:
//目標接口, 定義了統一的方法
interface Target {
public function method1();
public function method2();
}
//源角色
class Adaptee {
public function method1(){
echo 'Adaptee method1'.PHP_EOL;
}
//這個類沒有方法 method2
}
//適配器
class Adapter extends Adaptee implements Target {
//因爲Adaptee沒有方法 method2, 所以這裏要補充以實現接口Target的要求
public function method2(){
echo 'Adapter method2'.PHP_EOL;
}
}
$adapter = new Adapter();
$adapter->method1();
$adapter->method2();
對象適配器模式
對象適配器使用的是委派.
//目標接口, 定義了統一的方法
interface Target {
public function method1();
public function method2();
}
//源角色
class Adaptee {
public function method1(){
echo 'Adaptee method1'.PHP_EOL;
}
//這個類沒有方法 method2
}
//適配器
class Adapter implements Target {
private $_adaptee;
public function __construct(Adaptee $adaptee) {
$this->_adaptee = $adaptee;
}
//委託調用Adaptee的method1方法
public function method1(){
$this->_adaptee->method1();
}
//Adaptee類中沒有方法method2, 在這裏補充
public function method2() {
echo 'Adapter method2'.PHP_EOL;
}
}
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
$adapter->method1();
$adapter->method2();
-
類適配器採用"多繼承"的實現方式, 帶來了不良的高耦合, 一般不推薦使用
-
對象適配器採用"對象組合"的方式, 使用注入, 更符合松耦合的精神.
更多關於對象適配器可以參考: https://www.cnblogs.com/DeanChopper/p/4770572.html