Java结构型设计模式 —— 适配器模式适用于什么场景呢?

一、引言

来看生活中这样一个适配器案例,假设小编今年经费有限,来到了泰国旅游。

这一路上奔波的手机都没电了,到了酒店就打算充会电发现泰国插座用的都是两孔的,这个国内的插头用不了呀,就只好找酒店要了个多功能转换插头(适配器),这样才把电冲上。

适配器模式(Adapter Pattern),结构型设计模式

别名为包装器,将某个类的接口转换成客户端期望的另一个接口表示,主要目的就是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。

主要分为三大类:类适配器模式、对象适配器模式、接口适配器模式

二、适配器模式的工作原理

大家现在国内所看到的插头,电源输出一般是220V,但我们在给手机充电的时候,其实手机是不接受这个220V的电压的,所以充电器把220V的电压转换成手机所需要的电压,手机才能充电,这里设计到三个角色。

被适配者角色(Adaptee):对应的就是220V电压,这是插头默认的输出电压

适配者角色(Adapter):对应的就是手机充电器,手机充电器把22V电压,转换成手机所需要的电压

目标角色(Target):对应的是5V电压,最后手机所需要的电压。

1、将一个类的接口转换成另一个种接口,让原本接口不兼容的类可以兼容

2、从用户的角度看不到被适配者,是结耦的。

3、用户调用适配器转化出来的目标接口方法,适配器再调用被适配者相关接口方法。

4、用户接收到反馈,感觉只是和目标接口交互。

三、类适配器

我们来看看采用类适配模式,来怎么完成电压转换的问题。

1、首先我们要有一个被适配者类,来提供输出220V电压。

2、定义一个接口,规定输出5V电压,每个不同的充电器,有着不同的输出大小,这里规定的是5V。

3、定义适配器角色,实现刚刚所定义输出5V电压的接口,并且继承被适配者类获取220V的电压。

4、手机通过适配器来进行充电。

/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:36
 * @Description: 被适配者,输出220V电压
 */
public class Voltage200V {

    public int outPut220V() {
        System.out.println("被适配者 Voltage200V");
        return 220;
    }

}

/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:38
 * @Description: 定义输出5V电压接口
 */
public interface Voltage5V {

    int outPut5V();

}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:39
 * @Description: 适配器,这里是继承并且实现接口,并且进行电压转换
 */
public class VoltageAdapter extends Voltage200V implements Voltage5V {

    @Override
    public int outPut5V() {
        // 相当于电充电器插入插座的时候,获得了220V的电压
        int i = outPut220V();

        // 判断一下这个插座的输出的电压,符不符合充电器的标准
        if (i == 220) {
            // 符合标准就进行转换
            return 220 / 44;
        }
        return 0;
    }
}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:41
 * @Description: 手机
 */
public class Phone {

    /**
     * 充电的方法,需要传入一个5V电压的适配器,然后充电
     * @param voltage5V
     */
    public void Charge(Voltage5V voltage5V) {
        int i = voltage5V.outPut5V();
        System.out.println("获取到" + i + "V电压,可以充电");
    }

}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:42
 * @Description: 客户端
 */
public class Client {

    public static void main(String[] args) {
        // 首先的有一个手机
        Phone phone = new Phone();
        // 充电的时候要有一个充电器
        phone.Charge(new VoltageAdapter());
    }
}

四、对象适配器

对象适配器和类适配器是同一种思想,只不过实现方式略有区别,根据合成复用原则(少用继承,多用聚合组合)原则,使用聚合来代替继承。解决了类适配器继承局限性的问题,因为java中是单一继承的,提高了使用灵活性。

主要的区别就是改动了:适配器角色,代码如下:

/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:39
 * @Description: 适配器
 */
public class VoltageAdapter implements Voltage5V {

    // 通过构造器聚合的形式,这里直接采用的类,最好是定义成接口/父类
    private Voltage200V voltage200V;

    public VoltageAdapter(Voltage200V voltage200V) {
        this.voltage200V = voltage200V;
    }

    public int outPut5V() {
        if (null != voltage200V) {
            return 0;
        }
        // 获取220V电压
        int src = voltage200V.outPut220V();
        if (src == 220) {
            System.out.println("我是适配器:已将220V电压转换为5V电压");
            return src / 44;
        }
        return 0;

    }
}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 11:42
 * @Description: 客户端
 */
public class Client {

    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.Charge(new VoltageAdapter(new Voltage200V()));
    }
}

五、接口适配器

那接口适配是做什么呢? 假设我们项目之前有一个接口,里面提供了三个方法。但是的要求只需要实现里面其中一个方法即可,如果按照传统的方式去实现,那肯定是三个方法都要实现,这接口适配器就来了。

首先需要创建一个抽象类,实现该接口全部方法,都是默认实现,由该抽象类的子类有选择性的覆盖其中的方法。

在JDK类库的事件处理包java.awt.event中广泛使用了接口适配器模式,如WindowAdapter、KeyAdapter、MouseAdapter等。

/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 16:40
 * @Description: 接口定义
 */
public interface InterfaceAdapter {

    void method1();

    void method2();

    void method3();
}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 16:42
 * @Description: 抽象类,全部都是默认实现
 */
public abstract class AbstractAdapter implements InterfaceAdapter {

    @Override
    public void method1() {}

    @Override
    public void method2() {}

    @Override
    public void method3() {}
}
/**
 * @Auther: IT贱男
 * @Date: 2019/8/13 16:43
 * @Description:
 */
public class Client {

    public static void main(String[] args) {
        // 可以使用采用子类继承,选择重写部分方法,这里小编直接这样写了
        AbstractAdapter method = new AbstractAdapter() {
            @Override
            public void method1() {
                System.out.println("method1");
            }
        };
        method.method1();
    }
}

六、适配器注意事项

类适配器:采用继承

对象适配器:采用聚合组合

接口适配器:使用抽象类进行接口默认实现,子类有选择的进行覆盖实现

适配器模式最大的作用就是将原本不兼容的接口融合在一起工作,在实际开发中可根据实际情况来选择。

 

发布了152 篇原创文章 · 获赞 422 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/weixin_38111957/article/details/100886788