前言

适配器模式在Android开发中使用率很高,如ListViewRecyclerView

定义:适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作;

使用场景:

  • 系统需要使用现成的类,而此类的接口不符合系统的需要,即接口不兼容;
  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作;
  • 需要一个统一的输出接口,而输入端的类型不可预知;

适配器模式分为两种:类适配器模式对象适配器模式

类适配器模式

类适配器模式UML类图:

android dp 适配器 android适配器模式_android


Target:目标角色,也就是所期待得到的接口;

Adaptee:需要适配的接口;

Adapter:适配器角色,适配器把源接口转换为目标接口;

示例代码

这里以生活中的电源适配器举例,我们知道生活中的电压是220V,而手机充电电压则为5V,其实手机充电器就充当适配器的角色

  • 定义电压适配接口,相当于target角色,IVolt
/**
 * 电压适配接口,相当于target角色
 */
interface IVolt {
    //适配结果为5V
    fun getVolt5(): Int
}
  • 定义220V电压类,相当于adaptee角色,Volt220
/**
 * 220V电压,相当于adaptee角色
 */
open class Volt220 {
   protected fun getVolt220(): Int {
        return 220
    }
}
  • 定义电压适配器,将220V适配成5V电压,VoltAdapter
/**
 * 电压适配器,将220V适配成5V电压
 */
class VoltAdapter : Volt220(), IVolt {

    override fun getVolt5(): Int {
        return getVolt220() - 215 //模拟变压操作
    }
}
  • 编写测试类进行验证
object Test {
    @JvmStatic
    fun main(args: Array<String>) {
        val adapter = VoltAdapter()
        println("经过适配器适配后的电压:${adapter.getVolt5()}")
    }
}

结果输出:

经过适配器适配后的电压:5

缺点:由于是继承关系,被适配器类的函数在adapter中也可以调用;

对象适配器模式

对象适配器模式UML类图:

android dp 适配器 android适配器模式_android dp 适配器_02


可以看出与类适配器模式的区别主要在于适配器是持有需要适配的对象,通过这种形式来实现接口的适配;

这里我们同样以电压适配为例;

  • 定义电压适配接口,相当于target角色,IVolt
/**
 * 电压适配接口,相当于target角色
 */
interface IVolt {
    //适配结果为5V
    fun getVolt5(): Int
}
  • 定义220V电压类,相当于adaptee角色,Volt220
/**
 * 220V电压,相当于adaptee角色
 */
open class Volt220 {
    fun getVolt220(): Int {
        return 220
    }
}
  • 定义适配器类,VoltAdapter
/**
 * 电压适配器,将220V适配成5V电压
 */
class VoltAdapter(private val volt220: Volt220) : IVolt {

    override fun getVolt5(): Int {
        return volt220.getVolt220() - 215 //模拟变压操作
    }
}
  • 编写测试类验证
object Test {
    @JvmStatic
    fun main(args: Array<String>) {
        val adapter = VoltAdapter(Volt220())
        println("经过适配器适配后的电压:${adapter.getVolt5()}")
    }
}

结果输出:

经过适配器适配后的电压:5

Android源码中的适配器模式

  • ListView、RecyclerView的adapter,这里不再过多赘述;
  • Retrofit中将okhttp3.Call转变成为 retroift中的Call,感兴趣的小伙伴可以移步:Retrofit原理解析(二)

总结

优点:

  • 更好的复用性,系统需要使用现有的类,而此类的接口不符合系统的需要时,通过适配器模式就可以让功能得到复用;
  • 更好的扩展性,实现适配器功能时,可以调用自己开发的功能,从而自然地扩展系统的功能;

缺点:

  • 过多的使用适配器,会让系统非常乱,明明看到调用的是A接口,其实内部被适配成了B接口的实现,如果不是很有必要,建议直接对系统进行重构;

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )