适配器模式在我们的开发中使用率极高,代码中随处可见。像ListView 、GridView 、RecyclerView等都使用了Adapter。一般优化也会是对它的优化。
适配器模式的定义
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式的使用场景
1. 系统需要使用现有的类,而此类的接口不符合系统的需求,即接口不兼容。
2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
3. 需要一个统一的输出接口,而输入端的类型不可预知。
适配器模式的UML类图
角色介绍:
- 目标接口(Target),也就是所期待得到的接口,目标可以是具体的或抽象的类,也可以是接口。
- 需要适配的类(Adaptee):需要适配的类或适配者类。
- 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
适配器模式的代码实现:
注意: 适配器分为两种,类适配器模式和对象适配器模式
- 类适配器源码:
// Target 角色
public interface FiveVolt {
public int getVolt5();
}
// adaptee 角色,需要被转换的对象
public class Volt220 {
public int getVolt220(){
return 220;
}
}
// Adapter 角色,将220v的电压转换成5v的电压
public class VoltAdapter extends Volt220 implements FiveVolt {
@Override
public int getVolt5() {
return 5;
}
}
// 测试
public class Test {
public static void main(String[] args){
VoltAdapter adapter = new VoltAdapter();
System.out.println("输出电压为:"+adapter.getVolt5());
}
}
输出结果就不粘贴了,下面看下对象适配器模式
类适配器模式使用继承的关系连接到Adaptee类,而对象适配器使用代理关系连接到Adaptee类。
源码如下:
// Target 角色
public interface FiveVolt {
public int getVolt5();
}
// adaptee 角色,需要被转换的对象
public class Volt220 {
public int getVolt220(){
return 220;
}
}
// Adapter 角色,将220v的电压转换成5v的电压
public class VoltAdapter implements FiveVolt {
Volt220 mVolt220;
public VoltAdapter(Volt220 adaptee) {
this.mVolt220 = adaptee;
}
public int getVolt220() {
return mVolt220.getVolt220();
}
@Override
public int getVolt5() {
return 5;
}
}
测试类Test.java
// 测试
public class Test {
public static void main(String[] args){
VoltAdapter adapter = new VoltAdapter();
System.out.println("输出电压为:"+adapter.getVolt5());
}
}
对象适配器比类适配器更加灵活、实用。在使用Adapter模式的过程中建议尽量使用对象适配器的实现方式,多用合成或者聚合,少用继承。
总结
优点:
- 更好的复用性
系统需要使用现有的类,而此类的接口不符合系统的需要,那么通过适配器模式就可以让这些功能得到更好的复用。 - 更好的扩展性
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能
缺点:
- 过多地使用适配器,会让系统非常凌乱,不易整体把握。
例如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这样的接口,无异于一场灾难。因此,如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。