一、介绍
适配器模式主要是为了解决系统中两个接口实现某个或某类功能但又不兼容的问题,比如国内居民用电电压是220V,手机充电输入电压是5V,在给手机充电时需要将220V电压转换为5V,这个转换装置就可以理解为适配器,软件编程中有时也需要用到这种思想,解决这类问题就需要用到适配器模式。
适配器模式细分为类适配器模式、对象适配器模式和接口适配器模式三种。
二、示例
1、类适配器模式
类适配器模式是指适配器类通过继承源对象类,实现目标接口的方式,在适配器类中实现目标接口定义的方法,在实现方法中调用源对象类方法并作相关转换,从而输出想要的结果。
1.1、UML类图
类适配器模式
在这个例子中,Voltage5VAdapter适配器类继承源对象类Voltage220V,实现目标对象接口IVoltage5V,实现IVoltage5V接口中定义的out方法,通过调用Voltage220V类中output方法获得源对象输出的电压,转换成需要的电压输出,手机类Phone调用charging方法开始充电,客户端类Client实现整个系统的运行。
1.2、代码
public class Voltage5VAdapter extends Voltage220V implements Voltage5V{
@Override
public int out() {
return output()/44;
}
}
public class Phone {
public void charging(Voltage5VAdapter adapter){
if (adapter.out() > 5){
System.out.println("电压不对,无法充电");
}else {
System.out.println("充电中。。。");
}
}
}
1.3、小结
由于Java的单继承机制,在类适配器模式中,由于继承了源对象,所以目标对象只能是接口形式,这有一定的局限。同时继承也会使得父类中一些方法暴露给了子类,增加了耦合度。
2、对象适配器模式
为解决类适配模式中目标对象只能是接口的限制,对象适配器模式中,适配器类不再继承源对象,源对象以全局变量形式聚合到适配器类中,这样目标对象可以是接口也可以是抽象类,同时继承的减少,耦合度也降低。
2.1、UML类图
对象适配器模式
在这种模式下,源对象Voltage220V以全局变量的形式聚合到适配器类Voltage5VAdapter中,在构造方法中传入源对象实例,目标对象方法实现中通过源对象实例去调用相关方法做转换,最后输出结果。
2.2、代码
public class Voltage5VAdapter extends Voltage5V{
private final Voltage220V voltage220V;
public Voltage5VAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public int out() {
return voltage220V.output()/44;
}
}
public class Phone2 {
public void charging(Voltage5VAdapter adapter){
if (adapter.out() > 5){
System.out.println("电压不对不能充电");
}else {
System.out.println("充电中...");
}
}
}
2.3、小结
源对象以全局变量的形式聚合到适配器类中,目标对象可以是接口形式,也可以是抽象类形式,系统更加灵活。
3、接口适配器模式
接口适配器模式主要是为了解决实现类不需要实现接口中定义的全部方法这一问题,比如一个接口中定义了很多个方法,但实现者只用到其中一个,如果直接实现接口,那么全部方法都会以空实现的形式存在类中,实现类会显得臃肿,如果是匿名内部类去实现,那代码可读性更差,为解决这一问题,我们可以用一个抽象类去实现接口,外部调用传入抽象类,这样就可以需要哪个方法就只用实现哪个方法即可。
public interface IInterface {
void f1();
void f2();
void f3();
}
public abstract class AbsInterfaceAdapter implements IInterface{
@Override
public void f1() {
}
@Override
public void f2() {
}
@Override
public void f3() {
}
}
public class Main {
public static void main(String[] args){
AbsInterfaceAdapter adapter = new AbsInterfaceAdapter() {
@Override
public void f1() {
super.f1();
System.out.println("外部只实现f1方法");
}
};
adapter.f1();
}
}
三、总结
Android中适配器,最常见和常用那莫过于RecyclerView的Adapter了,在这套系统中,Adapter适配器主要是作为data和view的桥梁,解决数据显示在控件上的适配兼容问题,data作为源对象,以全局变量的形式聚合在adapter类中,同时adapter类实现了ViewHolder这个目标接口,通常我们需要自建一个类去实现ViewHolder接口,实现getItem(),在这个方法中通过findViewById找到各个控件返回,然后通过ViewHolder对象取到哥哥控件对象进行data赋值,这样数据就显示到了控件上,这里用到了对象适配器模式,由于类适配器模式的限制,平时开发中最常用的还是对象适配器模式。
学习了设计模式再结合到项目中,不得不感叹设计模式之类。