Java设计模式6:适配器模式(Adapter)

Adapter(适配器)模式

意图

将一个类的接口转换成客户希望的另一个借口。Adapter模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。也叫做包装器(Wrapper),可以理解为生活中的插座转换器。

#适用性

1、想使用一个已经存在的类,而他的接口不符合你的要求

2、你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作

3、想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配他们的接口。对象适配器可以适配它的父类接口

适配器模式的结构

适配器模式分为类的适配器模式和对象的适配器模式两种。

类的适配器:类的适配器模式把适配的类的API转换成为目标类的API。

对象的适配器:对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

类适配器结构

这里写图片描述

对象适配器结构

这里写图片描述

Target

定义Client使用的与特定领域相关的接口

Client

与符合Target接口的对象协同

Adaptee

定义一个已经存在的接口,这个接口需要适配

Adapter

对Adaptee的接口与Target接口进行适配

效果

类适配器

1、用一个具体的Adapter类对Adaptee和Target进行匹配。结果式当我们想要匹配一个类以及他的所有子类时,类Adapter将不能胜任工作

2、使得Adapter可以重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类

3、仅仅引入一个对象,并不需要额外的指针以间接得到Adaptee

对象适配器

1、允许一个Adapter和多个Adaptee,即Adaptee本身以及他的子类同时工作。Adapter也可以一次给所有的Adaptee添加功能

2、使得重定义Adaptee的行为比较困难。这就需要生成Adaptee的子类并且使得Adapter引用这个子类而不是引用Adaptee本身

示例

类的适配器
Target:期待得到的接口
package adapter;

/**
 * @Author fitz.bai
 * @Date 2018/8/28 17:37
 */
public interface Target {
    void read();

    void write();
}
Adaptee:已经存在的接口
package adapter;

/**
 * @Author fitz.bai
 * @Date 2018/8/28 17:39
 */
public class Adaptee {
    public void read() {
    }
}
Adapter:适配器
package adapter;

/**
 * @Author fitz.bai
 * @Date 2018/8/28 17:39
 */
public class Adapter extends Adaptee implements Target {
    @Override
    public void write() {

    }
}

解释一下:

现在我们期待一个接口里面(Target)有read和write两方法,现在呢,已经有一个接口里面(Adaptee)有一个read的方法。我们就希望能设计一个接口去适配一下Adaptee,然后多一个write方法,这样就符合需求了,所以我们可以继承Adaptee拿到read方法,实现Target接口,把Adaptee的API与Target的API衔接起来(适配)。实现write方法。

对象的适配器

前面的Target和Adaptee不变,适配器的实现如下:

package adapter;

/**
 * @Author fitz.bai
 * @Date 2018/8/28 17:47
 */
public class ObjectAdapter implements Target {
    private Adaptee adaptee;

    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void read() {
        this.adaptee.read();
    }

    @Override
    public void write() {
//        doSomething;
    }
}

解释一下:

这里和类适配器不同的是,Adapter和Adaptee是委派关系,在Adapter中关联被适配的类Adaptee,通过构造函数传入具体需要适配的被适配类的对象,然后通过委托的方式完成我们需要的方法。

为使Target能够使用Adaptee类里的read方法,故提供一个中间环节Adapter类(包装了一个Adaptee的实例),把Adaptee的API与Target的API衔接起来(适配)。

类的适配器模式

优点

  • 使用方便,代码简化
  • 仅仅引入一个对象,并不需要额外的字段来引用Adaptee实例

缺点

  • 高耦合,灵活性低
  • 使用对象继承的方式,是静态的定义方式

对象的适配器模式

优点

  • 灵活性高、低耦合
  • 采用 “对象组合”的方式,是动态组合方式

缺点

  • 使用复杂
  • 需要引入对象实例

Java 中适配器模式的使用

FileInputStream

在 OutputStream 类型中,所有的原始流处理器都是适配器类。ByteArrayOutputStream 继承了 OutputStream 类型,同时持有一个对 byte 数组的引用。它一个 byte 数组的接口适配成 OutputString 类型的接口,因此也是一个对象形式的适配器模式的应用。

FileOutputStream 继承了 OutputStream 类型,同时持有一个对 FileDiscriptor 对象的引用。这是一个将 FileDiscriptor 接口适配成 OutputStream 接口形式的对象型适配器模式。

Reader 类型的原始流处理器都是适配器模式的应用。StringReader 是一个适配器类,StringReader 类继承了 Reader 类型,持有一个对 String 对象的引用。它将 String 的接口适配成 Reader 类型的接口。

猜你喜欢

转载自blog.csdn.net/qq_22798455/article/details/82152191