结构型模式——适配器模式

结构型模式——适配器模式

(一)概述

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。例如,读卡器是作为内存卡和笔记本之间的适配器,我们将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

适配器模式一共有三个角色,从上面那个内存卡的例子也能看出来,主要分为:

1. 目标(Target)接口:当前系统业务所期待的接口,可以是抽象类或接口。
2. 适配者(Adaptee)类:被访问和适配的现存组件库中的组件接口。
3. 适配器(Adapter)类:一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

在这里插入图片描述
适配器模式非常简单,也很好理解。从代码实现的角度看,适配器模式又可以分为:类适配器模式、对象适配器模式。

下面是类适配器模式:

在这里插入图片描述
下面是对象适配器模式:

在这里插入图片描述

(二)类适配器模式

下面我们举一个手机充电器的例子来体会一下两种适配器模式。首先,电源输出为220V,充电器给手机充电的输出电压为5V,很显然,我们需要一个适配器来使得手机可以使用220V的电源充电。

首先我们先把电源写好:

public class Voltage220V {
    
    
    public int output220V() {
    
    
        int src = 220;
        System.out.println("电源输出" + src + "V");
        return src;
    }
}

然后写好充电器的输出接口:

public interface Voltage5V {
    
    
    int output5V();
}

适配器的作用就是将电源的220V降为可以给手机使用的5V:

public class VoltageAdapter extends Voltage220V implements Voltage5V {
    
    
    @Override
    public int output5V() {
    
    
        int src = super.output220V();
        int dst = src / 44;
        System.out.println("转换为" + dst + "V");
        return dst;
    }
}

然后写手机,手机只能用5V充电,因此我们这里要使用适配器而不是直接使用220V电源:

public class Phone {
    
    
    public static void charging(Voltage5V voltage5V){
    
    
        int v = voltage5V.output5V();
        if(v == 5){
    
    
            System.out.println("接收电压为5V,正常充电");
        }else if(v > 5){
    
    
            System.out.println("电压高于5V,无法充电");
        }
    }
}

然后来测试一下:

public void test(){
    
    
    Phone.charging(new VoltageAdapter());
}

我们可以发现类适配器模式的特点,适配器实现了目标接口同时也继承了适配者,这样适配器就同时具有了目标和适配者的特性,因此可以将两者进行转化。

(三)对象适配器模式

对象适配器和类适配器非常相似,只不过类适配器用的是继承而对象适配器用的是聚合而已,原理基本都是一样的。

还是上面那个例子,如果我们要把他修改成对象适配器模式,我们只需要修改一下适配器,将其改为聚合关系即可。

public class VoltageAdapter2 implements Voltage5V {
    
    
    private Voltage220V voltage220V;

    public VoltageAdapter2(){
    
    
        this.voltage220V = new Voltage220V();
    }

    @Override
    public int output5V() {
    
    
        int src = this.voltage220V.output220V();
        int dst = src / 44;
        return dst;
    }
}

测试一下:

public void test02(){
    
    
    Phone.charging(new VoltageAdapter2(new Voltage220V()));
}

(四)适配器模式总结

通过这个例子我们可以总结适配器模式的一些优点:

1. 灵活性好
2. 可以让两个没有关系的类一起运行
3. 增加了类的通透性

那类适配器和对象适配器具体的使用场景有什么区别呢?首先我们大家都知道java不支持多继承,而我们的类适配器必须要继承适配者,这也就说明如果要将适配器和目标建立关系,目标必须是一个接口,这也就带来了很大的局限性。

因此,对象适配器的出现解决了这个问题。对象适配器没有使用继承关系而是选用了聚合关系,避免了多继承的问题。也就是说,对象适配器的使用范围更广。

2020年8月1日

猜你喜欢

转载自blog.csdn.net/weixin_43907422/article/details/107730415