适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。

简单地说,就是需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它。

适配器分类:

  • 类适配器模式
  • 对象的适配器模式
  • 接口的适配器模式

注: 如果对类图中的箭头有疑惑参考: UML类图中的六种关系(物理设计阶段)

1. 类适配器模式


在Adapter中实现目标接口同时继承待适配类来完成适配:

Target 为目标接口类

Adaptee 为待适配类

Adapter 适配器类: 将Adaptee适配为Target接口

 

// 已存在的、具有特殊功能,但不符合我们既有的标准接口的类
class Adaptee {
    public void specificRequest() {
        System.out.println("被适配的类,该类具有特殊功能");
    }
}

// 目标接口
interface Target {
    public void request();
}

// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
    public void request() {
        System.out.println("普通类,该类具有普通功能");
    }
}

// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
    public void request() {
        super.specificRequest();
    }
}

//测试类
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();   //输出“普通类,该类具有普通功能”

// 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();     //输出“被适配的类,该类具有特殊功能”

2. 对象的适配器模式


与类适配器不同的是,对象适配器持有Adaptee对象而不需要继承它。

//只需要修改适配器类即可
//适配器类,只实现标准接口
class Adapter implements Target{
    private Adaptee adaptee;
    public Adapter (Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void request() {
        this.adaptee.specificRequest();
    }
}

//测试类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();  //输出“普通类,该类具有普通功能”


//Adapter需要先创建一个被适配类的对象作为参数
Target adapter = new Adapter(new Adaptee());
adapter.request();  //输出“被适配的类,该类具有特殊功能”
---------------------
作者:SEU_Calvin
来源:CSDN
原文:https://blog.csdn.net/SEU_Calvin/article/details/71126649 
版权声明:本文为博主原创文章,转载请附上博文链接!

3. 接口的适配器模式


大话设计模式中没有 接口适配模式,但是很多网上文章中还是提到了接口适配,所以这里也讲解一下:

目的:减少接口实现,Adaptee类只需要实现接口中的一部分

Wrapper:相当于适配器(这里的作用和抽象类功能相同)

Adaptee: 待适配的类,只实现了request接口而不需要实现cancel接口。

image

 

总结:

Adapter继承自Adaptee和Target的类来完成适配。

Adapter持有Adaptee对象并实现Target接口来完成适配(java类是单继承,最多只能继承一个类,对象适配器可以继承其它类)。

 

使用实例


1. Android中ListView通过ListAdapter加载每一条View,而不需要考虑各个view的不同

image

ListView   是client

ListAdapter 是 Target

BaseAdapter/ArrayAdapter/CursorAdapter 是 适配类

List<T>/Cursor 中保存了列表数据,需要适配成多个view展示到ListView上,它相当于 Adaptee

所以这里使用了: 类适配模式 + 接口适配模式

 

2.jdk中InputStreamReader/OutputStreamWriter

Reader/Writer : 相当于 Target

InputStreamReader 是 Adapter

InputStrea 是 Adaptee

所以这里使用了: 对象适配模式

3. jdk中Arrays.asList(T …a)

将 数组适配成List对象,这里好像和上面讲的三种模式都不像,它通过一个接口将一种对象类型数据转换为另一种类型数据:

输出类型List 作为 Target

asList接口  作为 Adapter

输入数组 a 是 Adaptee

 

参考:

《大话设计模式》

https://blog.csdn.net/SEU_Calvin/article/details/71126649

https://www.jianshu.com/p/78f6083ef869

版权声明:本文为NeilZhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/NeilZhang/p/10279549.html