前言
前面所涉及的工厂设计模式和建造者设计模式都是创建型模式。
而今天所讲解的适配器设计模式涉及到类与类的关系。
类与类的关系主要有两种:继承与组合,优先使用组合。而适配器模式就用到了组合。
定义
Adapter:定义一个包装类,用于包容不兼容接口的对象。
包装类->适配器Adapter
被包装对象->适配者Adaptee->被适配的类
作用:把一个类的接口转换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类一起工作。
类的适配器模式
简述:Target期待调用Request方法,而Adaptee中没有(这就是所谓的不兼容现象)。
解决方案:为使Target能够使用Adaptee类里的SpecificRequest方法,所以提供一个中间环节Adapter类(继承Adaptee,实现Target接口),把Adapter的API和Target的API衔接起来(适配)。
package 设计模式3
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
/**
* 目标接口:Target
*/
interface Target{
fun request()
}
/**
* 类源:Adaptee
*/
open class Adaptee{
fun selfRequest(){
println("selfRequest被调用了")
}
}
/**
* 适配器类
*/
class Adapter:Adaptee(),Target{
override fun request() {
this.selfRequest()
}
}
/**
* 测试
*/
fun main() {
val adapter = Adapter()
adapter.request()
}
对象的适配器模式
概述:Target期待调用Request方法,而Adapter并没有(不兼容现象)。
解决方案:为使Target能够使用Adaptee类中的SpecificRequest方法,故提供一个中间环节Adapter类(继承Adapter,实现Target接口),把Adapter的API和Target的API衔接起来(适配)。
package 设计模式3
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
/**
* 目标接口
*/
interface Target1{
fun request()
}
/**
* 源类
*/
open class Adaptee1{
fun selfRequest(){
println("selfRequest1被调用了")
}
}
/**
* 适配器类
*/
class Adapter1(val adaptee: Adaptee1):Adaptee1(),Target1{
override fun request() {
adaptee.selfRequest()
}
}
/**
* 测试
*/
fun main() {
val adapter1 = Adapter1(Adaptee1())
adapter1.request()
}
优点
- 更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
- 透明、简单:客户端可以调用同一端口,因而对客户端来说是透明的。这用做更简单并且更直接。
- 更好的扩展性:在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
- 解耦性:将目标和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改源代码。
- 符合开放-关闭原则:同一个适配器可以把适配者类和它的子类都适配到目标接口;可以为不同的目标接口实现不同的适配器,而不需要修改待适配类。
缺点
过多的使用适配器,会让系统非常凌乱,不易进行整体把握。
应用场景
Android系统中的使用:ListView和RecyclerView中均用到了适配器Adapter
- 系统需要重用现有类,而该类的接口不符合系统的需求,可以使用适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 多个组件功能类似,但接口不统一且可能会经常切换时,可使用适配器模式,使得客户端可以用统一的接口使用它们。
参考文章:
Android设计模式-适配器模式