适配器模式(Adapter)

适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类能够在一起工作。在生活中,我们的笔记本电脑经常需要连接很多外部设备,有时遇见电脑提供的接口与外设接口不一致。如视频接口,现在超薄笔记本提供的都是HDMI接口,但是连接到比较老的投影仪时需要VGA接口。此时我们需要一个HDMI和VGA的转换器。

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

在生活中,我们的笔记本电脑经常需要连接很多外部设备,有时遇见电脑提供的接口与外设接口不一致。如视频接口,现在超薄笔记本提供的都是HDMI接口,但是连接到比较老的投影仪时需要VGA接口。此时我们需要一个HDMI和VGA的转换器。如下图:

适配器模式(Adapter)

 

适配器模式的两种形式

适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。如下图:

适配器模式(Adapter)

上图中,左边是类的适配器模式(通过继承实现,即extends关键字),右边是对象的适配器模式(通过对象组合实现)。

类的适配器模式

类的适配器模式把被适配的类的API转换成为目标类的API,其静态结构如下图:

适配器模式(Adapter)

从上图可以看出,Adaptee类并没有showInfo()方法,而客户端则其他这个方法。为使客户端能够使用Adaptee类,提供一个中间类Adapter,把Adaptee的API与Traget类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类模式。

模式所涉及的角色有:

  • 目标(Target)角色:这是我们所期待得到的接口,注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

  • 源(Adaptee)角色:现有需要适配的接口。

  • 适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

Java代码如下:

// 适配器接口
public interface Target {
    // 原样的将信息输出
    public void show(String message);
}
 
// 被适配对象
public class Adaptee {
    public void showInfo(String message) {
        System.out.println("Adaptee=" + message);
    }
}
 
// 具体的适配器
public class Adapter extends Adaptee implements Target {
    @Override
    public void show(String message) {
        System.out.println("Adapter=" + message);
        super.showInfo(message);
    }
}
 
// 客户端
public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.show("hello adapter.");
    }
}

对象的适配器模式

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

适配器模式(Adapter)

从上图中可以看出,Adaptee类并没有show()方法,而客户端则期待这个方法。为了使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adapter与Adaptee是委派关系,这决定了这个适配器模式是对象的。

对象适配器模式设计的角色:

  • 目标(Target)角色:这是所期待的接口,目标可以是具体的或抽象类。

  • 源(Adaptee)角色:现有需要适配的接口。

  • 适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口,显然,这一角色必须是具体类。

Java代码如下:

// 适配器接口
public interface Target {
    // 原样的将信息输出
    public void show(String message);
}
 
// 被适配对象
public class Adaptee {
    public void showInfo(String message) {
        System.out.println("Adaptee=" + message);
    }
}
 
// 具体的适配器
public class Adapter implements Target {
    private Adaptee adaptee;
 
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
 
    @Override
    public void show(String message) {
        System.out.println("Adapter=" + message);
        this.adaptee.showInfo(message);
    }
}
 
// 客户端
public class Client {
    public static void main(String[] args) {
        Target target = new Adapter(new Adaptee());
        target.show("hello adapter.");
    }
}
我们一定要给自己提出这样的任务:第一,学习,第二是学习,第三还是学习。 —— 列宁
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号