适配器模式在我们的开发中使用率极高,从代码中随处可见的Adapter就可以判断出来。说到底,适配器是将两个不兼容的类融合在一起,它有点像粘合剂,将不同的东西通过一种转换使得它们能够协作起来。
适配器模式把一个类的接口换成客户端所期待的另一种接口,从而使原本因接口欧不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式也分两种,即类适配器模式和对象适配器模式,首先学习类适配器模式,结构图如下:
如图所示,类适配器是通过实现Target接口以及继承Adaptee类来实现接口转换,例如,目标接口需要的是operation2,但是Adaptee对象只有一个operation3,因此就出现了不兼容的情况。此时通过Adapter实现一个operation2函数将Adaptee的operation3转换为Target需要的operation2,以此实现兼容。
角色介绍:
用电源接口做例子,笔记本电脑的电源一般都是用5V电压,但是我没生活中的电线电压一般是220V,这时就出现了不匹配的状况,在软件开发中我们称为接口不兼容,此时就需要适配器来进行接口转换。
在上述电源接口这个示例中,5V电压就是Target接口,220V电压就是Adaptee类,而将电压从220V转换到5V就是Adapter。
package com.guifa.patterndemo.adapterpattern;
// Target角色
public interface FiveVolt {
public int getVolt5();
}
package com.guifa.patterndemo.adapterpattern;
// Adaptee角色,需要被转换的对象
public class Volt220 {
public int getVolt220() {
return 220;
}
}
package com.guifa.patterndemo.adapterpattern;
// Adapter角色,将220V的电压转换成5V电压
public class VoltAdapter extends Volt220 implements FiveVolt {
@Override
public int getVolt5() {
return 5;
}
}
package com.guifa.patterndemo.adapterpattern;
public class Test {
public static void main(String[] args) {
VoltAdapter adapter = new VoltAdapter();
int volt5 = adapter.getVolt5();
System.out.println("输出电压:" + volt5);
}
}
输出结果:
输出电压:5
Process finished with exit code 0
对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用代理关系连接到Adaptee类。示例代码如下:
package com.guifa.patterndemo.adapterpattern;
// Target角色
public interface FiveVolt {
public int getVolt5();
}
package com.guifa.patterndemo.adapterpattern;
// Adaptee角色,需要被转换的对象
public class Volt220 {
public int getVolt220() {
return 220;
}
}
package com.guifa.patterndemo.adapterpattern;
// Adapter角色,将220V的电压转换成5V电压
public class VoltAdapter implements FiveVolt {
private Volt220 volt220;
public VoltAdapter(Volt220 volt220) {
this.volt220 = volt220;
}
public int getVolt220() {
return volt220.getVolt220();
}
@Override
public int getVolt5() {
return 5;
}
}
package com.guifa.patterndemo.adapterpattern;
public class Test {
public static void main(String[] args) {
VoltAdapter adapter = new VoltAdapter(new Volt220());
int volt5 = adapter.getVolt5();
System.out.println("输出电压:" + volt5);
}
}
这种实现方式直接将要被适配的对象传递到Adapter中,使用组合的形式实现接口兼容的效果。这比类适配器方式更为灵活,它的另一个好处是被适配对象中的方法不会暴露处理,而类适配器由于继承了被适配对象,因此,被适配对象类的函数在Adapter类中也都含有,这使得Adapter类出现一些奇怪的接口,用户使用成本较高。因此,对象适配器模式更加灵活、实用。
Adapter模式的经典实现在于将原本不兼容的接口融合在一起,使之能够很好地进行合作。
优点:
缺点: