设计模式之适配器模式

830 阅读5分钟

适配器模式.png

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

欢迎来到今天的学习,今天我们一起来学习下使用频率不是很高的但是极易搞懂的一种模式----适配器模式。多唠叨几句,我本月将会对java的设计模式精讲,欢迎点击头像,关注我的专栏,我会持续更新,加油!

系列文章:

设计模式之单例模式

设计模式之工厂模式

设计模式之建造者模式

设计模式之代理模式

设计模式之访问者模式

...持续更新中

话不多说,进入正题

适配器模式

顾名思义,该模式肯定是为了为兼容而生的。适配两个本来不兼容的事物,可以将两者友好相处,协同工作。

该模式的原始定义为:将类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作。

注意:该定义中明确说明了适配器模式的关键点就在于转换而转换时要在已有的接口基础上做好兼容。

我们也可以拿生活当中的例子更加形象的解释。比如我们开会时用的投影仪,本电脑开放出来的接口,和大屏上的接口不兼容,这时候需要一个中间的适配器来转换下。

我们程序员一般都需要分屏,一个写代码,一个看文档,一个查资料,将三个屏幕连接在一起不一定所有的接口就适用。像本人的mac电脑就不兼容,mac电脑上只开放了mac的扁形接口。还得自己买个适配器(该适配器开放了vga,HDMI,网络线插口),那么这个适配器,起到了无可替代的作用(下图即是适配器,也叫扩展器)

image.png

根据类图拆分讲解

适配器模式的通用类图如下:

image.png

从改图可以看到三个关键角色(也就是图中黄色部分)

  • 目标类, 用户期待的连接口,适配器类即将要进行适配的抽象类或接口;

  • 适配器类, 可以是类或接口,是作为具体适配者类的中间类来使用;

  • 具体适配者类, 可以是内部的类或服务,也可以是外部对象或服务。

其实不难发现,适配器模式封装了三个重要事实

  • 具体适配者类可以有不同的接口

  • 用户在使用适配器类时实际上使用了多个接口;

  • 适配器类和具体适配者类引入了变化。

如下简图所示,适配器模式的类实际上是作为中间者来封装变化的。

image.png

下面我们根据实际代码来深入理解下

代码展示

场景:拿我们程序员用mac连接一个分屏的场景,根据我们上面所说的类图和讲解来写下代码(一定要看注释)

//创建Target接口
public interface Target {
    //这是源类Adapteee没有的方法
    public void Request(); 
}


//创建源类(Adaptee)
public class Adaptee {
    
    public void SpecificRequest(){
    }
}


//创建适配器类(Adapter)
//适配器Adapter继承自Adaptee,同时又实现了目标(Target)接口。
public class Adapter extends Adaptee implements Target {

    //目标接口要求调用Request()这个方法名,但源类Adaptee没有方法Request()
    //因此适配器补充上这个方法名
    //但实际上Request()只是调用源类Adaptee的SpecificRequest()方法的内容
    @Override
    public void Request() {
    
        //重要:
        //适配器只是将SpecificRequest()方法作了一层封装,封装成Target可以调用的Request()而已
        //这里就是兼容,就是转换,把我们苹果电脑的接口利用适配器(扩展器)连接到了分屏上
        this.SpecificRequest();
    }
}

接下来,定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标

public class AdapterPattern {

    public static void main(String[] args){
        Target mAdapter = new Adapter();
        //看似调用request. 其实是SpecificRequest,
        mAdapter.Request();
    }
}

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

总结

个人认为当你碰到以下几种情况的时候可以使用该模式:

  • 原有接口无法修改时

  • 适配不同数据格式时

  • 需要过渡升级旧接口时(比如app升级需要一个审核期,但是后台代码一下子就更新了)

适配器模式优点我认为还是很多的,然后得到也就意味要牺牲一些。所有的模式都一样

优点:

  • 解耦:将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码

  • 扩展性强: 在实现适配器功能的时候,可以调用自己开发的功能,任意扩展

  • 符合开放-关闭原则:同一个适配器可以把适配者类和它的子类都适配到目标接口;可以为不同的目标接口实现不同的适配器,而不需要修改待适配类

缺点嘛:我认为有以下几点:

1、如果适配器使用太多,会导致臃肿,整体系统会非常凌乱。

2、修改目标接口会导致所有适配接口都需要定制修改

3、一次只能适配一个抽象类或接口(因为java是单继承,多实现);

弦外之音

OK 今天的适配器就讲到这里,感谢你的阅读,如果你感觉学到了东西,麻烦您点赞,关注。

我已经将本章收录在专题里,点击下方专题,关注专栏,我会每天发表干货,本月我会持续输入设计模式。

加油! 我们下期再见