适配器模式
介绍
顾名思义,就是要做到适配的作用,类似于电源适配器,转换进电达到出电固定。将两个不兼容电融合到一起,粘合剂到作用。把一个类到接口变换成客户端所期待到另一种接口,从而使得原本接口不匹配无法在一起工作到两个类能够在一起工作。
Android中到ListView、GridView、RecycleView都需要使用到的Adpater则使用到了适配器模式。ListView使用的Adapter缓存的View,在getView中无论如何定义布局,返回的都是View。RecycleView的Adapter中缓存的ViewHolder,在onCreateViewHolder中返回。
UML
类适配器
- Target : 目标角色,期待得到的接口。类适配器,该目标不可以是类
- Adaptee : 源接口,需要被转换适配的接口
- Adapter : 适配器角色,把源接口转换成目标接口。这一角色不可以是接口,是具体类。
对象适配器
对象适配器,使用代理关系连接到Adaptee类。通过适配器类来衔接。
使用场景
- 需要使用现有的类,但是接口不符合系统要求,需要转换一下
- 想要建立一个可重复使用的类,用于与一些彼此之间没有太大关联的一些类。包括一些可能在将来引进的类一起工作
- 需要一个统一的输出接口,输入端的类型不可预知
事例
一. 类适配器
比如顾客要一束花,但是店里的都是一朵一朵的,那么就需要有个转换操作,将话拼装成一束.
- 目标接口:提供想要实现的方法
/**
* 目标,一束花
*/
public interface TargetFlower {
/**
* 获取一束花
* @return
*/
String getOneBindFlower();
}
- 被转换类:一朵花
/**
* 被转换的花
*/
public class AdapteeFlower {
/**
* 获取一朵花
*
* @return
*/
protected String getFlower() {
return "一朵花";
}
}
- 转换类对象:继承被转换类,实现目标接口
/**
* 转换花,类适配器
* 1. 继承被适配者
* 2. 实现目标接口
*/
public class ClasAdapterFlower extends AdapteeFlower implements TargetFlower {
@Override
public String getOneBindFlower() {
//获取被转换的值,再各种转换,后返回为一束花
String flower = getFlower();
return "一束花";
}
}
- 测试:
//类适配器方式
ClasAdapterFlower clasAdapterFlower = new ClasAdapterFlower();
System.out.println(clasAdapterFlower.getOneBindFlower());
//看这里诸事掉的,它还能获取到被适配着的方法
// clasAdapterFlower.getFlower();
- 输出:
一束花
这里能看到,通过获取转换类的方式,来使用,则将被转换类给转换了,但实际上,被转换的方法依旧可以被调用,会造成比较混乱的局势。
二. 对象适配器
对象适配器,主要就是将继承被适配着改为引用被适配者
- 对象适配器:
/**
* 对象适配器:
* 1. 实现目标接口
* 2. 以组合的方式
*/
public class ObjAdapterFlower implements TargetFlower {
/**
* 持有被适配者
*/
private AdapteeFlower adapteeFlower;
/**
* 设置被适配者
*
* @param adapteeFlower
*/
public void setAdapteeFlower(AdapteeFlower adapteeFlower) {
this.adapteeFlower = adapteeFlower;
}
/**
* 获取一束花
* @return
*/
@Override
public String getOneBindFlower() {
//获取被适配者花flower
String flower = adapteeFlower.getFlower();
return "一束花";
}
}
- 测试:
//对象适配器方式
ObjAdapterFlower objAdapterFlower = new ObjAdapterFlower();
objAdapterFlower.setAdapteeFlower(new AdapteeFlower());
System.out.println(objAdapterFlower.getOneBindFlower());
输出就不贴了,也是一样的。通过以上两种方式,那么能明显看出孰优孰劣了,对象适配器的一个好处,被适配对象中的方法不会被暴露出来,所以这里使用对象适配器方式是优于类适配器方式的。
总结:Adapter模式主要思想就是将不符合要求的输入,转换为符合要求的输出,起到适配的效果。使用Adapter模式尽量使用对象适配器的方式,平时也推荐简易多用合成或聚合,少用继承,当根据具体情况而定。