适配器模式(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 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号