概念
适配器模式是指将一个接口转换为客户希望的另外一个接口,该模式使得原本不兼容的类可以一起工作。实现了由“源”到“目标”的适配,适配器负责把“源”过度到“目标”。
模式结构
例如Apple手机Android手机的充电器接口不兼容,在专卖店购买苹果手机时一般都会带一个充电器转换头,一个小小的插头,链接在安卓手机充电器端就可以为苹果手机充电。这里包含几种设备也就是对应适配器模式结构中的几种桔角色。
- 源角色(Adeptee 安卓手机充电器):需要被适配的接口
- 目标抽象角色(Target 苹果充电器接口):客户所期待要使用的接口
- 适配器(Adepter 转换器):将安卓手机充电器接口转换为苹果手机充电器接口,即把源接口转换成符合要求的目标接口(即可以为苹果充电还保留了给安卓充电的功能)
- 客户端(Client 苹果手机):使用目标角色的设备
两种适配器模式
类适配器模式
这种适配器模式就是主要用于单一的为某个类而实现适配器的一种模式。
示例代码
/**
* 客户端
*/
public class AdpterClient {
public static void main(String[] args){
AppleCharger target = new Adapter();
target.chargeForApple();
target.chargeForAndroid();
}
}
/**
* 源-Adaptee
*/
class AndroidCharger{
public void chargeForAndroid(){
System.out.println("为Android手机充电");
}
}
/**
* 目标-Target
*/
interface AppleCharger{
void chargeForAndroid();
void chargeForApple();
}
/**
* 适配器-Adapter
*/
class Adapter extends AndroidCharger implements AppleCharger{
@Override
public void chargeForApple() {
System.out.println("为Apple手机充电");
}
}
输出结果:
为Apple手机充电
为Android手机充电
也许会有人问为什么不直接在“源”中添加方法?其实适配器是为了实现某种目的而为源类暂时性的添加某种功能方法,所以不能直接改变原结构。再说,这也不符合Java高内聚低耦合的要求。适配器Adapter类继承了AndroidCharder类,Java属于单继承语言,所以Adapter不能再继承其他类了,这样适配器就只为AndroidCharger这一个类服务,所以称为类适配器。
对象适配器模式
对象适配器是把“源”作为一个对象聚合到适配器类中。
例如上例中适配器代码如下
class Adapter1 implements AppleCharger{
AndroidCharger androidCharger = new AndroidCharger();
public Adapter1(AndroidCharger androidCharger) {
this.androidCharger = androidCharger;
}
@Override
public void chargeForAndroid() {
androidCharger.chargeForAndroid();
}
@Override
public void chargeForApple() {//新增方法
System.out.println("为Apple手机充电");
}
//如果技术能实现我还以为电脑充电,即实现了为多个源进行适配的功能
}
客户端改为
public class AdpterClient {
public static void main(String[] args){
AppleCharger target = new Adapter1(new AndroidCharger());
target.chargeForApple();
target.chargeForAndroid();
}
}
运行结果:同上
两种适配器模式总结
- 类的适配器用于单一源的适配,源的单一化决定代码实现不用写逻辑选择,结构清晰
- 对象适配器可以用于多源的适配,弥补了类适配器的不足,但同时增加了实现代码的逻辑选择复杂度,结构不太清晰
- 默认适配器我们想实现一个接口,但不想实现接口的所有方法,只想实现部分时用默认适配器,在接口和具体实现类之间添加一个抽象类,用抽象类去实现目标接口的所有方法,而具体的实现类继承抽象类,只需要覆盖其需要完成的部分方法即可。
默认适配器示例
interface Code{
void codeJava();
void codeC();
void codePhp();
}
abstract class CodeDefault implements Code{
public void codeC() {
}
public void codeJava() {
}
public void codePhp() {
}
}
class CodeImpl extends CodeDefault{
@Override
public void codeJava() {
System.out.println("我只会用Java语言写代码");
}
}