适配器模式一篇就够了

2019-07-10  本文已影响0人  JamFF

很常用的结构型设计模式,用做两个不兼容的接口之间的桥梁,结合了两个独立接口的功能。

经常看到有人滥用,并且会和策略模式桥接模式混淆,这里主要结合例子说明下,如何恰当的引入的适配器模式,过度使用造成的问题后面也会提到。

使用场景

一、需求

中国标准电压是 220V,电器也是支持 220V的,代码实现使用电器的逻辑。
创建电器类:

public class ChinaDevice {

    /**
     * 使用电器
     *
     * @param voltage 输入电压
     */
    public void use(int voltage) {
        System.out.println("输入电压" + voltage + "V");
        if (voltage == 220) {
            System.out.println("中国电器正常运行");
        } else {
            System.out.println("中国电器烧毁");
        }
        System.out.println();
    }
}

创建电源类:

public class ChinaPower {
    public void run(ChinaDevice device) {
        // 使用220V电压运行
        device.use(220);
    }
}

使用电器:

public class DeviceUnitTest {

    @Test
    public void test() {
        // 创建220V电源
        ChinaPower chinaPower = new ChinaPower();
        // 创建电器
        ChinaDevice device = new ChinaDevice();
        // 运行电器
        chinaPower.run(device);
    }
}

开发完成,电器正常运行起来了。

输入电压220V
中国电器正常运行

二、拓展需求

产品经理拿来一个美国电器,仅支持 110V 电压,要求也要正常运行。

考虑到每个国家电器标准都不一样,需求必然会经常变更,这次我们抽离出一个接口:

public interface Device {

    /**
     * 使用电器
     *
     * @param voltage 输入电压
     */
    void use(int voltage);
}

创建美国电器类:

public class USADevice implements Device {

    @Override
    public void use(int voltage) {
        System.out.println("输入电压" + voltage + "V");
        if (voltage == 110) {
            System.out.println("美国电器正常运行");
        } else {
            System.out.println("美国电器烧毁");
        }
        System.out.println();
    }
}

美国电器使用 220V 必然烧毁,那么应该如何解决呢?

很简单,创建一个美国电源类就可以了:

public class USAPower {
    public void run(Device device) {
        device.use(110);
    }
}

这种方式当然没有问题,但是随着国家的增多,电源类也会越来越多。

从实际生活的角度看,我们也不可能拥有多个电压的电源,只能借助变压器(适配器)来解决该问题。

三、引入适配器模式

创建一个 220V 的适配器:

public class ChinaAdapter implements Device {

    private USADevice mUsaDevice;

    /**
     * 默认中国电器
     */
    public ChinaAdapter() {

    }

    /**
     * 适配美国电器
     */
    public ChinaAdapter(USADevice usaDevice) {
        this.mUsaDevice = usaDevice;
    }

    @Override
    public void use(int voltage) {
        System.out.println("输入电压" + voltage + "V");
        if (mUsaDevice != null) {// 适配美国电器
            if (voltage == 110) {
                System.out.println("美国电器正常运行");
            } else {
                System.out.println("适配器工作...进行变压");
                voltage = 110;
                System.out.println("美国电器在" + voltage + "V正常运行");
            }
        } else {// 默认中国电器
            if (voltage == 220) {
                System.out.println("中国电器正常运行");
            } else {
                System.out.println("中国电器烧毁");
            }
        }
        System.out.println();
    }
}

仔细对比 ChinaAdapterChinaDevice,可以发现,这个适配器只是扩展了 ChinaDevice,使其支持 USADevice 美国电器,本质上还是中国电器。

使用适配器:

public class DeviceUnitTest {

    @Test
    public void test() {
        // 创建220V电源
        ChinaPower chinaPower = new ChinaPower();
        // 适配器
        Device device = new ChinaAdapter(new USADevice());
        chinaPower.run(device);
        // 默认构造,就是支持220V的中国电器
        device = new ChinaAdapter();
        chinaPower.run(device);
    }
}

项目下载地址

四、优势

在这种模式下,电源不需要知道是哪种电器,只要提供 220V 电压即可,具体操作的什么类,由适配器决定。

适配器模式具有以下优势:

  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 灵活性好。

总结

参考

适配器模式
适配器和策略模式的联系与区别

上一篇 下一篇

猜你喜欢

热点阅读