定义
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 --- 《设计模式》GOF
Adapter模式的宗旨就是,基于现有类所提供的服务,向客户端提供接口,以满足客户的期望。---《java设计模式 》
存在意义
先举个例子:比如我们现在的智能手机,充电器都是USB接口的,直接接到电脑的USB端口上充电,但是由于我没带电脑,我们就必须通过一个插销,把USB线连接到插销上,再把插销插到插座上充电,这里的插销中间件就相当于适配器。
USB是不能插到插座上的,这个大家都知道,但是为了充电,我们创造了适配器,适配器就是我们能充电的介质。我们的目的就是用他来充电,或者服务我们充电,这样理解应该没错。大家想想,我们在写代码的时候,有时候客户想要一种功能(USB传输线充电),我们的插座提供这种功能(充电),但是由于他们的接口名称,或者方法名称不一直,所以USB和插座不能直接充电,所以要统一适配器来做个桥接,这样在软件应用中是存在需求的,比如我们有一种实现的代码(插座)能完成某项功能,但是和客户的接口不一样,所以不能直接使用,这时用适配器模式就很有必要了,通过一种模式来服用功能(充电)。
下面我们就写代码举个充电的例子:
/**
* 我们的插座,可以给任何电话充电
* @author test
*
*/
public class Plug
{
//我们提供的插座可以给各种电话充电
public void phoneCharge()
{
System.out.println("链接插头,充电");
}
}
插座就相当于我们以前实现过的功能,我们需要复用他,实现现有的功能
/**
* 客户想要的功能,给自己手机充电
* @author test
*
*/
public interface Charge
{
//客户需要的接口,苹果手机充电
public void iphoneCharge();
}
通过以上可以看出,客户想要的接口和我们生产的接口不一样,不能直接进行充电
/**
* 通过插销来衔接USB数据线和插座充电
* @author test
*
*/
public class Snib implements Charge
{
//引入插座,插销链接数据线和插座进行充电
public Plug plug;
public Snib(Plug plug)
{
this.plug=plug;
}
//通过插销,满足客户苹果手机的充电
public void iphoneCharge() {
plug.phoneCharge();
}
}
链接,解决问题,over
大家发觉,上面这写代码,是通过引入,构造是传入plug来完成的,这就是经典的对象适配器模式了。
如果是类适配器的话,我们插销类就可以不用引入插座,直接继承插座的功能,在客户需要充电功能的时候,直接调用插座的充电功能就行了,但是行是行,不建议在java用多使用类是适配器
以下是网上的总结:
效果及优缺点:
对于类适配器:
1. 用一个具体的Adapter类对Adaptee和Taget进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。
2. 使得Adapter可以override(重定义) Adaptee的部分行为,因为Adapter是Adaptee的一个子类。
对于对象适配器:
1. 允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter也可以一次给所有的Adaptee添加功能。
2. 使得override(重定义)Adaptee的行为比较困难。如果一定要override Adaptee的方法,就只好先做一个Adaptee的子类以override Adaptee的方法,然后再把这个子类当作真正的Adaptee源进行适配。