1、定义
适配器模式简单来说就是将一个接口转换成另一种接口,从而让原本不兼容的接口能够兼容。
从用户的角度感觉不到被适配者,实现了解耦,用户调用适配器转换出来的接口方法,适配器再调用被适配接口的相关方法,被适配的接口对于用户来说是透明,用户也无需关心被适配的接口。
2、使用场景
① 对于不兼容类型的接口进行转换。
② 在输入有很多种,输出只有一种的情况,可以使用适配器进行统一输出,如ListView的Adapter,不管用户的ItemView是什么类型,getView方法只返回View。
3、UML类图
类适配器:通过多重继承的方式,分别继承目标者接口和被适配者类来实现适配,其中继承目标接口达到适配的目的,继承被适配者类,通过调用被适配者类的方法来实现转换成目标接口的功能。
对象适配器:使用组合的方式,通过继承目标接口来达到适配的目的,同时适配器持有被适配者的引用,以此来调用被适配者的方法来实现接口转换的功能。
4、代码实现
1、类适配器
/**
* 目标接口,也就是希望通过适配器转换得到的接口
*/
public interface Target {
/**
* 输出5V电压
*/
int getVolt5();
}
/**
* 类适配器
* <p>
* 被适配的类
*/
public class ClassAdaptee {
/**
* 输出220V电压
*
* @return
*/
public int getVolt220() {
return 220;
}
}
/**
* 类适配器,不如对象适配器灵活
* <p>
* 希望通过适配器将220V转化成5V电压,但是还是Target类型
* <p>
* 通过多重继承目标接口和被适配者类方式来实现适配
* 多重继承,其中继承的目标接口的部分来达到适配的目的,继承被适配者类的部分来达到通过调用被适配者
* 类里面的方法来实现目标接口的功能
*/
public class ClassAdapter extends ClassAdaptee implements Target {
@Override
public int getVolt5() {
return 5;
}
}
2、对象适配器简单实现
/**
* 目标接口,也就是希望通过适配器转换得到的接口
*/
public interface Target {
/**
* 输出5V电压
*/
int getVolt5();
}
/**
* 对象适配器
* <p>
* 被适配对象
*/
public class ObjectAdaptee {
/**
* 输出220V电压
*
* @return
*/
public int getVolt220() {
return 220;
}
}
/**
* 对象适配器,内部持有被适配对象,更加灵活,通过继承Target,使陪适配对象转化成Target类型的
* <p>
* 对象适配器使用组合的方式实现适配,被适配对象可以是不同的子类,更加灵活
* <p>
* ListView的适配器就是对象适配器,被适配对象为itemView
* <p>
* 适配器和装饰者的区别,适配器将一种接口转换成另一种接口,实现了两种接口的转换
* 装饰者是对目标接口进行包装和扩展
*/
public class ObjectAdapter implements Target {
private ObjectAdaptee objectAdaptee;
public ObjectAdapter(ObjectAdaptee objectAdaptee) {
this.objectAdaptee = objectAdaptee;
}
public int getVolt220() {
return objectAdaptee.getVolt220();
}
@Override
public int getVolt5() {
return 5;
}
}
5、总结
优点:① 良好的复用性,现有类的接口不符合需求,这是可以通过适配器对接口功能进行转换,是现有的功能很好的得到复用。
② 良好的扩展性,不修改原有代码的情况下,在适配的时候可以对原有的功能进行扩展。
类适配器和对象适配器比较:
- 对象适配器使用的是组合模式,比类适配器更加灵活。
- 对象适配器中被适配的方法不会暴露出来,类适配器由于继承了被适配对象,因此被适配对象的函数在Adapter类中也含有,导致Adapter被接口污染。
适配器模式、装饰者模式和代理模式在结构上有很大的相似性:
适配器模式:将被适配者现有的功能转换成目标功能。
装饰者模式:对被装饰者进行功能的增加和扩展。
代理模式:对被代理者的接口进行控制。
Android源码应用:ListView的Adapter就是对象适配器,被适配对象为itemView
代码:https://gitee.com/os2chen/DesignPattern
参考:《Head First Design》、《Android源码设计模式解析与实战》