适配器模式是一种很简单的软件设计模式,它允许将现有的类(方法)用作另一个接口.它通常用于使现有类(方法)与其他类(方法)一起工作而无需修改其源码.

适配器模式看起和装饰者模式、代理模式看起来很像.但它们在设计目的上还是有不同的:

  • 适配器模式主要是用来解决两个已有接口之间不匹配的问题,它不考虑这些接口具体的实现,也不考虑它们将如何演化.适配器不需要改变已有的接口,就能够使它们协同作用.
  • 装饰者模式和代理模式也不会改变原有对象的接口,但装饰者模式的作用是为了给对象增加功能.代理模式是为了控制对象的访问,通常也只包装一次.

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 考虑一个有猎人的游戏,他猎杀狮子。
// 首先,我们有一个Lion所有类型的狮子必须实现的接口
interface Lion
{
public function roar();
}

class AfricanLion implements Lion
{
public function roar()
{
}
}

class AsianLion implements Lion
{
public function roar()
{
}
}
// 猎人期望任何Lion接口的实现都可以进行搜索。
class Hunter
{
public function hunt(Lion $lion)
{
$lion->roar();
}
}

//现在让我们说我们必须WildDog在我们的游戏中添加一个,以便猎人也可以追捕它。但我们不能直接这样做,因为狗有不同的界面。为了使它与我们的猎人兼容,我们将不得不创建一个兼容的适配器

// This needs to be added to the game
class WildDog
{
public function bark()
{
}
}

// Adapter around wild dog to make it compatible with our game
class WildDogAdapter implements Lion
{
protected $dog;

public function __construct(WildDog $dog)
{
$this->dog = $dog;
}

public function roar()
{
$this->dog->bark();
}
}

// 而现在WildDog可以在我们的游戏中使用WildDogAdapter。
$wildDog = new WildDog();
$wildDogAdapter = new WildDogAdapter($wildDog);

$hunter = new Hunter();
$hunter->hunt($wildDogAdapter);