适配器模式, 也叫做Adapter模式,他的完整定义是:
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
在生活中也有一些适配器的实例,比如说我们的插座,一般我们的插座是两孔的,但是有些大功率的电器比如空调啊,冰箱之类的,他们就是三孔的。而为了使两孔三孔都能够正常的使用,所以我们的插座一般都有三孔的实现。但是电线我们都知道是由正负两根线组成,所以说三孔插座也只是两孔有用而已。这就是典型的适配器。
在软件学中的适配器,其实有一下三种角色:
1. 目标接口(Target): 也就是客户所期待的接口,可以是具体的或者抽象类,也可以是接口。
2. 需要适配的类: 通常是与目标接口不相同的类,比如上面例子中的空调插线。
3. 适配器类: 通过包装一个需要适配的对象,将愿接口转换成目标接口。
在讲解适配器模式的具体实现时,我们先来看看适配器模式的UML图:
具体的实现代码如下:
//目标接口,只接受正负两极
abstract class Target{
abstract function doubleHole();
}
//空调类,被适配者
class AirCondition {
//有一个可以插入三个插孔的方法
public function threeHole(){
echo "我通电了";
}
}
//适配器类
class Adapter extends Target{
public $aircondition;
public function __construct(){
$this->aircondition = new Aircondition();
}
public function doubleHole(){
$this->aircondition->threeHole();
}
}
在上面的代码中,首先有一个target类,该类就是目标接口,他只接受两孔插头,然后定义了一个空调的类,空调的插头是三个,所以我们不能直接的去实现,这就需要一个适配器类去给我们进行一个适配。在适配器中,必须要持有空调对象的引用,然后去继承或者实现Target。通过代码我们可以看到,在doubleHole()方法里面去直接调用aircondition的 threeHole方法,这样就将空调的三孔插孔给匹配上了。这就是适配器模式的实现方式。
总结:其实适配器在使用的时候多少有点亡羊补牢的感觉,因为无法更改现有的代码而做出的一个无奈之举。因为在软件的设计过程中,我们如果有能力去改变类的行为,那么就应该使其与接口匹配,但是在是无法改变其行为的时候(比如说引入的第三方库),那么就可以使用适配器模式进行一个适配的过程。