LXX的网络日志
人因梦想而伟大
聊聊适配器模式与外观模式

适配器模式的介绍

适配器模式(Adapter Pattern),顾名思义就是适配的意思。举个例子:Type-C的接口无法给IPhone充电,所以还要一个转接头,在Type-C上带上IPhone接口的头,这样就可以给IPhone充电了。

在我们的代码中也是一样,但我们接口出现不兼容的时候,就可以通过适配器将接口的数据进行转换,从而能适配接口。

它的原理很简单,适配器有两种实现方式:一种是类适配器,一种是对象适配器。其中,类适配器是使用继承关系来实现,对象适配器是使用组合关系来实现。

具体的,可以通过代码来看看它的实现:

其中,Target表示成要转化成的接口定义。Adaptee是一组不兼容Target接口定义的接口。Adaptor将Adaptee转换成符合Target接口定义的接口。

类适配器,基于继承:

public interface Target {
    void f1();
    void f2();
    void fc();
}

public class Adaptee {
    void fa() {
        // ...
    }
    void fb() {
        // ...
    }
    public void fc() {
        // ...
    }
}

public class Adaptor extends Adaptee implements Target {
    @Override
    public void f1() {
        super.fa();
    }

    @Override
    public void f2() {
        // 重写f2实现
    }

    // fc 方法无需实现,直接继承Adaptee即可
}

对象适配器,基于组合:

public class Adaptor implements Target {
    private final Adaptee adaptee;

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

    @Override
    public void f1() {
        // 委托给Adaptee
        adaptee.fa();
    }

    @Override
    public void f2() {
        // 重写f2
    }

    @Override
    public void fc() {
        adaptee.fc();
    }
}

两种适配器的实现方式,在实际项目中,对象适配器可能比类适配器更合适,因为继承只能继承一个类。不过,也不全都是如此,可能有些时候两个类大部分的方法都是相同的,只是有一部分的差别。这个时候用类适配器会更好,代码相对也会比较少。

在工作中,可能会遇到一些问题就是说,以前写的一些接口有一些兼容性的问题,一改的话就需要大改,这样的风险太大了,于是就需要适配器,做一些处理解决兼容性的问题。

在实际项目中,像一些数据类型的转换,就比较适合用适配器模式,例如上层的数据类型可能是Byte,想要转换成String、或者自定义的实体类,上层与下层并不是同一种的类型,而且在代码每一个使用到都要自己手动做转换,是非常麻烦的一件事情,重复代码可能会很多。

这个时候,只需要去实现一个适配器,然后使用到这些类型的实现类,都去继承适配器,然后读取数据去做一些业务上的一些操作。

外观模式的介绍

外观模式(Facade Pattern),为子系统提供一组统一的接口,定义一组高层接口让子系统更容易使用。

关于外观模式的介绍,可能说的很简洁很抽象。但在实际项目中,却是经常用到的,或者类似与外观模式的思想。

举个例子,我有一个订单取消的接口,在客户端看来我只是点了一些取消的按钮,但是服务端却做了很多操作,比如校验数据、判断订单状态、然后又分子订单和主订单,都要去分别的查询数据和校验。如果让客户端一个个的去调用接口,去查询结果然后显示出来这太麻烦了,而且工作量还大。

这个时候,就要将这些接口封装起来,客户端只需要传一个订单编号过来,调用封装好这些操作的接口即可,就能完成想要的操作。调用接口的次数从多次,变成了一次,减少了网络的开销,也提高了效率。

对于这些接口的调用者来说,我无需知道接口里面具体是怎么操作的,我只知道我传给你设定好的操作,然后能完成操作返回我想要的数据就好了。