适配器模式 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