有一家创业公司,需要做一个具有购物和论坛两种功能的网站。为了节省开发成本,决定用一套开源的购物网站和一套开源的论坛站进行修改上线。在进行两套系统的用户合并的过程中,开发人员有点犯难了。两套系统的用户表结构都不一样。用户操作类也不一样。例如,我要查询一个用户的详细信息。在不同的系统中,实现不一样,返回结果也不一样。如下:
class Shop_User {
//根据用户ID查询用户信息
public function getInfo($userId)
{
//数据库中查询到的返回结果,已省略查询代码
return array(
'user_name' => 'andrew',
'sex' => 'male',
'tel' => '138********',
'address' => '北京市',
);
}
}
class Forum_User {
//根据用户ID查询用户信息
public function getInfo($userId)
{
//数据库中查询到的返回结果,已省略查询代码
return array(
'username' => 'andrew',
'sex' => 'male',
'tel' => '138********',
'birth' => '1999-01-01',
);
}
}
我们可以看到,由于两套系统的结构不一样,返回的结果也不一样。但是有一些公用的信息,我们是需要的。那么,我们就把我们需要两套系统的所有信息合并起来,建立一个通用的查询类。记住一点,我们不需要去改它内部数据库结构和查询功能代码,否则会陷入无限的修改泥潭。很多程序员都深受其害。那么我们如何做到呢?有如下几种方案:
方案一:完全利用组合。即建立两个对象,分别获取两套系统的信息,然后做合并处理,
class User {
//购物网站用户
protected $_shopUser;
//论坛用户
protected $_forumUser;
//初始化
public function __construct()
{
$this->_shopUser = new Shop_User();
$this->_forumUser = new Forum_User();
}
//根据用户获取
public function getInfo($userId)
{
$shopUser = $this->_shopUser->getInfo($userId);
$forumUser = $this->_forumUser->getInfo($userId);
$shopUser['forum_user_name'] = $forumUser['username'];
$shopUser['birth'] = $forumUser['birth'];
return $shopUser;
}
}
方案二:利用继承和组合。
class User extends Shop_User
{
//论坛用户
protected $_forumUser;
public function __construct()
{
$this->_forumUser = nwe Forum_User();
}
//定义一个新方法用来获取用户信息
public function getUserInfo($userId)
{
$shopUser = $this->getInfo($userId);
$forumUser = $this->_forumUser->getInfo($userId);
$shopUser['forum_user_id'] = $forumUser['username'];
$shopUser['birth'] = $forumUser['birth'];
return $shopUser;
}
}
这样,我们的通用类就可以工作了,同时,我们把这个通用类叫做适配器。现实中也有很多这样的例子。例如,我们在大陆的电器插头在香港是用不了的,于是,我们可以到淘宝把一个转接头,就可以到香港使用了。这个转接头就是适配器了。还有大街上有很多应急充电设备,都会提供各种接口,各种形式的手机都可以在这里充电。这个通用的应急充电设备也可以叫适配器。适配器要解决的就是这种兼容性问题。
上面的例子我们仅举了一个查询用户信息的例子。其实,对于两个系统的整合,有很多兼容性处理的地方。我们在整合的时候,千万记住,只要把不同的地方用适配器的方式对不同的实现接口进行整合。这样我们无需调整表结构,也无需更改内部查询数据的代码实现,就可以完美地实现两个系统的整合。这么看来,适配器模式的作用还是蛮大的。