适配器模式:我真的不难

栏目: 后端 · 发布时间: 6年前

内容简介:前面三篇文章分别学习了单例模式、三种工厂模式和建造者模式,它们都是比较常用的创建型模式,顾名思义就是创建对象的。从这篇文章开始来学习结构型设计模式,今天是第一篇——适配器模式。首先拿我使用的小米手机为例,它撤销了原来的 Audio 接口,要使用耳机听歌呢,就必须使用 Type-C to Audio 转接线(如下图),一头接上手机,一头接上耳机线。(ps:话说,每次听歌和充电都要换来换去的,好麻烦)其实,这就是一个实际的适配器,和设计模式中的适配器扮演着同样的角色,将一个接口转换为另一个接口,以符合用户的期望

前面三篇文章分别学习了单例模式、三种工厂模式和建造者模式,它们都是比较常用的创建型模式,顾名思义就是创建对象的。从这篇文章开始来学习结构型设计模式,今天是第一篇——适配器模式。

适配器模式

首先拿我使用的小米手机为例,它撤销了原来的 Audio 接口,要使用耳机听歌呢,就必须使用 Type-C to Audio 转接线(如下图),一头接上手机,一头接上耳机线。(ps:话说,每次听歌和充电都要换来换去的,好麻烦)

适配器模式:我真的不难

其实,这就是一个实际的适配器,和 设计模式 中的适配器扮演着同样的角色,将一个接口转换为另一个接口,以符合用户的期望。

改进前

下面我们就将这个例子转换为代码,看它是如何实现的。以前的手机呢,有两个接口,使用 TypeC 接口充电:

public interface TypeCInterface {
    // 充电
    void chargeWithTypeC();
}

public class TypeCInterfaceImpl implements TypeCInterface {

    @Override
    public void chargeWithTypeC() {
        System.out.println("使用 Type-C 接口充电");
    }
}
复制代码

使用 Audio 接口听歌:

public interface AudioInterface {
    // 听歌
    void listenWithAudio();
}

public class AudioInterfaceImpl implements AudioInterface {

    @Override
    public void listenWithAudio() {
        System.out.println("使用 Audio 接口听歌");
    }
}
复制代码

而我们的手机,同时有这两个接口,用来充电和听歌:

public class XiaomiPhone {

    private AudioInterface audioInterface;
    private TypeCInterface typeCInterface;
    
    public XiaomiPhone(AudioInterface audioInterface, TypeCInterface typeCInterface) {
        this.audioInterface = audioInterface;
        this.typeCInterface = typeCInterface;
    }
    
    public void charge() {
        typeCInterface.chargeWithTypeC();
    }
    
    public void listen() {
        audioInterface.listenWithAudio();
    }
}
复制代码

而我们就可以用手机来边充电,边听歌了:

public class Client {

    public static void main(String[] args) {
        AudioInterface audioInterface = new AudioInterfaceImpl();
        TypeCInterface typeCInterface = new TypeCInterfaceImpl();
        
        XiaomiPhone xiaomiPhone = new XiaomiPhone(audioInterface, typeCInterface);
        xiaomiPhone.charge();
        xiaomiPhone.listen();
    }
}
复制代码

改进了

本来这一切都好好的,可是小米手机把 Audio 接口取消了,我们没法直接使用来听歌了。于是,我们只好使用转接线,将 Type-C 接口转为 Audio 接口:

// 需将其转换为 Audio 接口,所以实现了 AudioInterface
public class TypeCToAudioTieline implements AudioInterface {

    private TypeCInterface typeCInterface;

    // 另一头是 TypeC,所以传入 TypeCInterface
    public TypeCToAudioTieline(TypeCInterface typeCInterface) {
        this.typeCInterface = typeCInterface;
    }

    @Override
    public void listenWithAudio() {
        // ···
        typeCInterface.chargeWithTypeC();
    }
}
复制代码

然后呢,把转接线插入到手机上(把手机和转接线看作一个整体,它只有 Audio 接口了):

public class XiaomiPhone {

    private AudioInterface audioInterface;

    public XiaomiPhone(AudioInterface audioInterface) {
        this.audioInterface = audioInterface;
    }

    public void listenWithAudio() {
        audioInterface.listenWithAudio();
    }
}
复制代码

于是,现在我们就通过转接线,将 Type-C 接口转换成了 Audio 接口。然后将耳机插在转接线上,就可以听歌了:

public class Client {

    public static void main(String[] args) {
        TypeCInterface typeCInterface = new TypeCInterfaceImpl();
        TypeCToAudioTieline tieline = new TypeCToAudioTieline(typeCInterface);

        XiaomiPhone xiaomiPhone = new XiaomiPhone(tieline);
        xiaomiPhone.listenWithAudio();
    }
}
复制代码

上述模式就是适配器模式,它将一个类的接口转换成用户所需要的另一个接口,使得原本接口不兼容的类可以一起工作。

它的 UML 图如下:

适配器模式:我真的不难

下面我们来总结适配器模式的优点:

  • 它可以通过适配器进行接口的转换,让原本不兼容的类协同工作;
  • 这可以使客户从实现的接口解耦,如果被适配者改变了接口,适配器可以将其封装起来,客户不必跟随其修改;

缺点:

  • 增加一个适配器,可能会增加系统的复杂度。

适配器模式的具体实践

JDK#InputStreamReader

通过 InputStreamReader,可以将 InputStream 字节流转换为字符流进行处理。

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;
    
    // 将 inputStream 转换为 InputStreamReader
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }
    
    public int read() throws IOException {
        return sd.read();
    }
}
复制代码

Spring#AOP/MVC

另外,比如在 Spring AOP 中,将 Advice 封装成对应的拦截器类型。或是在 Spring MVC 中,通过适配器模式,用于执行目标 Controller 中的请求处理方法。

由于对其源码不太熟悉,这里也就不详细说了。感兴趣的小伙伴可以看看这篇文章。


以上所述就是小编给大家介绍的《适配器模式:我真的不难》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

上瘾

上瘾

[美] 尼尔·埃亚尔、[美] 瑞安·胡佛 / 钟莉婷、杨晓红 / 中信出版集团 / 2017-5 / 49.00元

——为什么我们会习惯性地点开某个App? ——这种使用习惯到底是如何养成的? ——为什么有些产品能让我们戒不掉,而其他的产品却不行? ——是否有什么秘诀能让用户对你的产品形成使用习惯,欲罢不能? 《上瘾》揭示了很多让用户形成使用习惯,甚至“上瘾”的互联网产品服务背后的基 本设计原理,告诉你怎样打造一款让用户欲罢不能的产品。作者根据自己多年的研究、咨询及实际经验,提出了新颖而......一起来看看 《上瘾》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具