首先我们来看一下适配器是什么,在生活中有哪些适配器的列子呢?比如我们的国外电压为
110V
,而我们国家的电压为
220V
,这就造成了很多时候我们在国外带回来的电器不能够使用,这时我们就可以使用一下电源适配器,类比到软件开发中就是:适配器模式的作用是解决两个软件试题间的接口不兼容的问题,我们在以一个例子来解释一下,比如我们的公司A开发的客户端,公司B开发的类库,之前由于没有进行命名规则的统一,导致我们的公司A将用使用的公司B的接口在客户端写成了AA,而B公司为其提供的接口叫做BB,由于A,B两家公司都比较难以更改接口名字,于是这个时候我们的适配器模式就派上了用场。
这种模式只是一种亡羊补牢,在初始设计时没有必要使用这种模式
好下面我们来用php
来实现一下适配器模式,我们模仿的场景是姚明刚刚去到美国时,姚明英语不好,与队友无法交流,需要翻译来代替。
首先我们来看一下不需要翻译的球员们的类:
abstract class Player {
protected $name;
public function __construct ($name) {
$this->name = $name;
}
abstract public function attack();
abstract public function defense();
}
class Forwards extends Player {
public function __construct ($name) {
parent::__construct($name);
}
public function attack () {
echo "前锋". $this->name ."进攻";
}
public function defense () {
echo "前锋". $this->name . "防守";
}
}
class Center extends Player { // 与前锋类似 }
class Guards extends Player { // 与前锋类似 }
好这样对于美国球员来说自然是没有问题的,但是对于姚明来说很有可能在刚刚去到美国时听不懂attack与defense,所以这时姚明需要借助一个翻译类:
class ForeginCenter {
private $name;
public function __construct ($name) {
$this->name = $name;
}
public function jingong () {
echo "外籍中锋". $this->name ."进攻";
}
public function fangshou () {
echo "外籍中锋". $this->name . "防守";
}
}
class Translator extends Player {
private $waijie;
public function __construct ($name) {
$this->waijie = new ForeginCenter($name);
parent::__construct($name);
}
public function attack () {
$this->waijie->jingong();
}
public function defense () {
$this->waijie->fangshou();
}
}
// 调用进攻
$yao = new Translator("姚明");
$yao->attack();
在前端中采用这种模式:
假如我们要渲染广东省地图,我们写下了如下代码:
var getGuangDongCity = function () {
var gungdongCity = [
{
name: "guangzhou",
id: 1
},
{
name: "shenzhen",
id: 2
}
];
return gungdongCity;
};
var render = function (fn) {
console.log("开始渲染地图");
console.log("模拟渲染:" + JSON.stringify(fn()));
};
render(getGuangDongCity);
但是,后来我们又发现了一份更为好的资料,其要求数据结构为:
var guangdongCity = {
guangzhou: 1,
shenzhen: 2
};
而我们又不想大动干戈的进行修改渲染页面的代码,也就是render
内的代码,于是我们可以编写一个用于数据格式转换的适配器。
var addressAdapter = function (oldAddressfn) {
var address = {},
oldAddress = oldAddressfn();
for (var i = 0, c; c = oldAddress[i++];) {
address[c.name] = c.id;
console.log(address);
}
return function () {
return address;
}
};
// 调用
render(addressAdapter(getGuangDongCity));