「设计模式」适配器模式

250 阅读3分钟

一、概述

适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。

适配器模式涉及3个角色:

  • (Adaptee):它是被访问和适配的现存组件库中的组件接口(相当于typec充电线)。
  • 适配器(Adapter):通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者(相当于转接头)。
  • 目标(Target):当前系统业务所期待的接口,它可以是抽象类或接口(相当于lightning充电线)。

主要有3种实现方式:类适配器对象适配器接口适配器

二、优缺点

优点

客户端通过适配器可以透明地调用目标接口。 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。 在很多业务场景中符合开闭原则。

缺点

适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

三、实现方式

下面从「安卓转苹果充电」为例,场景是:我手中有一部苹果手机,但是苹果手机只能用 Lightning 充电线,我这里只有 TypeC 充电线怎么办呢?弄个转接头,将TypeC 转换成为 Lightning 就可以使用了。

类适配器

通过继承来实现适配器功能。当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。

源适配者类

public class TypeCAdaptee {
    public void chargeAndroid(){
        System.out.println("typeC Android 充电口");
    }
}

目标接口类

public interface LightningTarget {
    void chargeIphone();
}

适配器类

public class Adapter extends TypeCAdaptee implements LightningTarget{

    @Override
    public void chargeIphone() {
        chargeAndroid();
    }
}

客户端类

public class Clienter {
    public static void main(String[] args) {
        LightningTarget lightningTarget = new Adapter();
        lightningTarget.chargeIphone();
    }
}

对象适配器

通过组合来实现适配器功能。对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。

源适配者类

public class TypeCAdaptee {
    public void chargeAndroid(){
        System.out.println("typeC Android 充电口");
    }
}

目标接口类

public interface LightningTarget {
    void chargeIphone();
}

适配器类

public class Adapter implements LightningTarget {

    private TypeCAdaptee typeCAdaptee;

    public Adapter(TypeCAdaptee typeCAdaptee){
        this.typeCAdaptee = typeCAdaptee;
    }

    @Override
    public void chargeIphone() {
        typeCAdaptee.chargeAndroid();
    }
}

客户端类

public class Clienter {
    public static void main(String[] args) {
        LightningTarget lightningTarget = new Adapter(new TypeCAdaptee());
        lightningTarget.chargeIphone();
    }
}

接口适配器

接口适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是“平庸”的实现,也就是说,这些方法都是空方法。而具体的子类都要继承此抽象类。

接口类

public interface A {
    void a();
    void b();
    void c();
    void d();
}

适配器类

public class Adapter implements A{
    @Override
    public void a() {

    }

    @Override
    public void b() {

    }

    @Override
    public void c() {

    }

    @Override
    public void d() {

    }
}

实现类

public class AInstance extends  Adapter{
    @Override
    public void a() {
        System.out.println("实现方法a");
    }

    @Override
    public void b() {
        System.out.println("实现方法b");
    }
}

客户端类

public class Clienter {
    public static void main(String[] args) {
        A a = new AInstance();
        a.a();
        a.b();
    }
}

四、应用场景

  • 封装有缺陷的接口设计
  • 统一多个类的接口设计,比如一个支付系统,有三种不同的支付方式,微信支付、支付宝支付、网银支付,这三种支付的实现方法都不一样,那么我们可以用适配器模式,让他们对外具有统一的方法,这样,我们在调用的时候就非常的方便。
  • 兼容老版本的接口,这个在我们系统升级中经常会用到。