适配器模式

介绍

顾名思义,就是要做到适配的作用,类似于电源适配器,转换进电达到出电固定。将两个不兼容电融合到一起,粘合剂到作用。把一个类到接口变换成客户端所期待到另一种接口,从而使得原本接口不匹配无法在一起工作到两个类能够在一起工作。

Android中到ListView、GridView、RecycleView都需要使用到的Adpater则使用到了适配器模式。ListView使用的Adapter缓存的View,在getView中无论如何定义布局,返回的都是View。RecycleView的Adapter中缓存的ViewHolder,在onCreateViewHolder中返回。

UML

类适配器

  • Target : 目标角色,期待得到的接口。类适配器,该目标不可以是类
  • Adaptee : 源接口,需要被转换适配的接口
  • Adapter : 适配器角色,把源接口转换成目标接口。这一角色不可以是接口,是具体类。

对象适配器

对象适配器,使用代理关系连接到Adaptee类。通过适配器类来衔接。

使用场景

  • 需要使用现有的类,但是接口不符合系统要求,需要转换一下
  • 想要建立一个可重复使用的类,用于与一些彼此之间没有太大关联的一些类。包括一些可能在将来引进的类一起工作
  • 需要一个统一的输出接口,输入端的类型不可预知

事例

一. 类适配器

比如顾客要一束花,但是店里的都是一朵一朵的,那么就需要有个转换操作,将话拼装成一束.

  1. 目标接口:提供想要实现的方法
/**
 * 目标,一束花
 */
public interface TargetFlower {
    /**
     * 获取一束花
     * @return
     */
    String getOneBindFlower();
}
  1. 被转换类:一朵花
/**
 * 被转换的花
 */
public class AdapteeFlower {
    /**
     * 获取一朵花
     *
     * @return
     */
    protected String getFlower() {
        return "一朵花";
    }
}
  1. 转换类对象:继承被转换类,实现目标接口
/**
 * 转换花,类适配器
 * 1. 继承被适配者
 * 2. 实现目标接口
 */
public class ClasAdapterFlower extends AdapteeFlower implements TargetFlower {
    @Override
    public String getOneBindFlower() {
        //获取被转换的值,再各种转换,后返回为一束花
        String flower = getFlower();
        return "一束花";
    }
}
  1. 测试:
//类适配器方式
        ClasAdapterFlower clasAdapterFlower = new ClasAdapterFlower();
        System.out.println(clasAdapterFlower.getOneBindFlower());
        //看这里诸事掉的,它还能获取到被适配着的方法
//        clasAdapterFlower.getFlower();
  1. 输出:
一束花

这里能看到,通过获取转换类的方式,来使用,则将被转换类给转换了,但实际上,被转换的方法依旧可以被调用,会造成比较混乱的局势。

二. 对象适配器

对象适配器,主要就是将继承被适配着改为引用被适配者

  1. 对象适配器:
/**
 * 对象适配器:
 * 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 "一束花";
    }
}
  1. 测试:
//对象适配器方式
        ObjAdapterFlower objAdapterFlower = new ObjAdapterFlower();
        objAdapterFlower.setAdapteeFlower(new AdapteeFlower());
        System.out.println(objAdapterFlower.getOneBindFlower());

输出就不贴了,也是一样的。通过以上两种方式,那么能明显看出孰优孰劣了,对象适配器的一个好处,被适配对象中的方法不会被暴露出来,所以这里使用对象适配器方式是优于类适配器方式的。

总结:Adapter模式主要思想就是将不符合要求的输入,转换为符合要求的输出,起到适配的效果。使用Adapter模式尽量使用对象适配器的方式,平时也推荐简易多用合成或聚合,少用继承,当根据具体情况而定。