概念
适配模式是把一个类的接口变成客户端期待的另外一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作。
适配器模式中的角色
适配者角色:需要被适配的对象或者类型。
适配器角色:通过包装一个需要适配的角色,从而将适配的角色的接口转换成目标接口。
目标接口角色:客户端所期待的接口,可以是具体类、抽象类、接口。
优缺点
优点:可以让任何两个没有关联的类一起运行,提高了类的复用,增加了类的透明度,灵活性好。
缺点:过多地使用适配器,会让系统非常零乱,维护成本高。
运用实例
这里我们通过一个手机耳机孔适配的例子进行说明。现在有一个圆孔的耳机和一个typc接口的手机,那么要怎么才能让接口不匹配的耳机能够使用呢?这个时候就需要一个转接线了。
基于类的适配器模式
首先实现我们的耳机类。
public class Headset {
public void circleEar(){
System.out.println("圆的耳机头");
}
}
然后抽象出一个接口,这个接口是我们客户端期待的接口(即手机期待的typc接口的耳机)
public interface TargetEar {
void typecEar();
}
最后我们通过适配器来继承圆孔的耳机类,并实现这个期待的typc接口。
public class EarAdapter extends Headset implements TargetEar{
private Headset headset;
public EarAdapter(Headset headset) {
this.headset = headset;
}
public void typecEar(){
super.circleEar();
System.out.println("提供一根转接线,将圆孔转成typc");
}
}
测试结果:
public class AdapterTest {
public static void main(String[] args) {
EarAdapter earAdapter = new EarAdapter();
earAdapter.typecEar();
}
}
圆的耳机头
提供一根转接线,将圆孔转成typc
可以看到我们成功的将圆孔转换成了typc接口。
基于对象的适配器模式
通过构造方法将适配对象传进去,不再继承适配者类。
public class EarAdapter implements TargetEar{
private Headset headset;
public EarAdapter(Headset headset) {
this.headset = headset;
}
public void typecEar(){
headset.circleEar();
System.out.println("提供一根转接线,将圆孔转成typc");
}
}
类适配器与对象适配器的区别
基于类的适配器使用的是继承的方式,所以无法对适配者的子类提供适配。基于对象的适配器使用的是组合的方式,可以对适配者和其子类提供适配,且对象适配器增加新的行为十分方便,同时适用于所有的适配者类。
基于组合/聚合优于继承的原则,使用对象适配器是更好的选择。但具体问题应该具体分析,某些情况可能使用类适配器会适合,最适合的才是最好的。