定义
适配器是作为两个不兼容的接口之间的桥梁,这种类型的设计模式数据结构型设计模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子:macbook电脑是没有网线插孔的,在没有无线网络的环境下macbook电脑只能通过增加一个转换器,然后网线查到转换器上实现上网功能,这里面转换器扮演的就是适配器的角色
作用
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
结构
电脑适配器模式结构图代码实现:
/**
* 网线类
* Class Adaptee
*/
class Adaptee
{
public function request()
{
echo "可以上网了";
}
}
/**
* 适配器接口
* Interface NetToUsb
*/
interface NetToUsb
{
public function handleRequest();
}
/**
* 适配器类
* Class Adapter
*/
class Adapter implements NetToUsb
{
private $adaptee;
public function __construct(Adaptee $adaptee)
{
$this->adaptee = $adaptee;
}
public function handleRequest()
{
echo "连接网线成功\n";
$this->adaptee->request();
}
}
/**
* 具体电脑类
* Class MacBook
*/
class MacBook
{
private $adapter;
public function __construct(NetToUsb $adapter)
{
$this->adapter = $adapter;
}
public function net()
{
$this->adapter->handleRequest();
}
}
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
$computer = new MacBook($adapter);
$computer->net();
//输出:网线连接成功可以上网了
开发业务应用场景
-
兼容老版本接口,在做版本升级的时候,对于一些要废弃的接口,我们不直接将其删除,而是暂时保留,并且标注为 deprecated,并将内部实现逻辑委托为新的接口实现。这样做的好处是,让使用它的项目有个过渡期,而不是强制进行代码修改。这也可以粗略地看作适配器模式的一个应用场景。
-
封装有缺陷的接口设计,假设我们依赖的外部系统在接口设计方面有缺陷(比如包含大量静态方法),引入之后会影响到我们自身代码的可测试性。为了隔离设计上的缺陷,我们希望对外部系统提供的接口进行二次封装,抽象出更好的接口设计,这个时候就可以使用适配器模式了。
-
统一多个类的接口设计,某个功能的实现依赖多个外部系统(或者说类)。通过适配器模式,将它们的接口适配为统一的接口定义,然后我们就可以使用多态的特性来复用代码逻辑。
-
替换依赖的外部系统,当我们把项目中依赖的一个外部系统替换为另一个外部系统的时候,利用适配器模式,可以减少对代码的改动。
-
适配不同格式的数据,适配器模式主要用于接口的适配,实际上,它还可以用在不同格式的数据之间的适配。比如,把从不同征信系统拉取的不同格式的征信数据,统一为相同的格式,以方便存储和使用。再比如,Java 中的 Arrays.asList() 也可以看作一种数据适配器,将数组类型的数据转化为集合容器类型。
网友评论