设计模式 - 适配器模式

100 阅读3分钟

image.png

适配器模式分为两种

  1. 类适配器:通过单继承的方式获取适配器
  2. 对象适配器:通过注册对象的方式获取适配器,常见用法

类适配器

代码文件如下

image.png

客户端类:想上网的电脑,但没有合适的网线

/**
 * 客户端类:USB接口的电脑,想上网,但没有网线
 */
public class Computer {

    /**
     * 客户端找一个转接头上网
     */
    public void net(NetToUsb adapter) {
        // 上网的实现,找一个转接头
        adapter.handleRequest();
    }
}

发现有一根非USB的网线,需要转接头

/**
 * 被适配的对象:非USB网线
 */
public class Adapt {

    public void request() {
        System.err.println("连上网络了");
    }
}

制作不同的转接头

/**
 * 转接口的抽象类
 */
public interface NetToUsb {

    /**
     * 提供转接功能,让非USB网线连接上USB接口
     */
    void handleRequest();
}
/**
 * 真正的适配器:处理USB接口与USB网线的连接功能
 *
 * 原理:适配器(通过继承)获取固定网线后实现转接方法,不支持热插拔
 */
public class Adapter extends Adapt implements NetToUsb {
    @Override
    public void handleRequest() {
        super.request();
    }
}

上网

/**
 * 通过固定的网线上网,用户无法热插拔网线
 */
public class Test {

    public static void main(String[] args) {
        Computer computer = new Computer();
        Adapter adapter = new Adapter();

        computer.net(adapter);
    }
}

对象适配器

客户端类:想上网的电脑,但没有合适的网线

/**
 * 客户端类:USB接口的电脑,想上网,但没有网线
 */
public class Computer {

    /**
     * 客户端找一个转接头上网
     */
    public void net(NetToUsb adapter) {
        // 上网的实现,找一个转接头
        adapter.handleRequest();
    }
}

发现有一根非USB的网线,需要转接头

/**
 * 被适配的对象:非USB网线
 */
public class Adapt {

    public void request() {
        System.err.println("连上网络了");
    }
}

制作不同的转接头

/**
 * 转接口的抽象类
 */
public interface NetToUsb {

    /**
     * 提供转接功能,让非USB网线连接上USB接口
     */
    void handleRequest();
}
/**
 * 真正的适配器:处理USB接口与USB网线的连接功能
 *
 * 原理:适配器(通过注册对象)获取需要的网线后实现转接方法
 */
public class Adapter implements NetToUsb {

    private Adapt adapt;

    public Adapter(Adapt adapt) {
        this.adapt = adapt;
    }

    @Override
    public void handleRequest() {
        adapt.request();
    }
}

上网

/**
 * 上网,支持用户热插拔
 */
public class Test {
    public static void main(String[] args) {
        Computer computer = new Computer();
        Adapt adapt = new Adapt();
        Adapter adapter = new Adapter(adapt);

        computer.net(adapter);
    }
}

对象适配器的改良,支持热插拔不同的对象

客户端类:想上网的电脑,但没有合适的网线

/**
 * 客户端类:USB接口的电脑,想上网,但没有网线
 */
public class Computer {

    /**
     * 客户端找一个转接头上网
     * @param adapter
     */
    public void net(NetToUsb adapter) {
        // 上网的实现,找一个转接头
        adapter.handleRequest();
    }
}

发现有许多不同的网线,需要转接头

/**
 * 被适配的对象:不同的网线
 */
public interface Adapt {

    void request();
}
/**
 * 网线1
 */
public class Adapt1 implements Adapt {
    @Override
    public void request() {
        System.err.println("上网1");
    }
}
/**
 * 网线2
 */
public class Adapt2 implements Adapt {
    @Override
    public void request() {
        System.err.println("上网2");
    }
}

制作不同的转接头

/**
 * 转接口的抽象类
 */
public interface NetToUsb {

    /**
     * 提供转接功能,让非USB网线连接上USB接口
     */
    void handleRequest();
}
/**
 * 真正的适配器:处理USB接口与USB网线的连接功能
 *
 * 原理:适配器(通过注册对象)获取需要的网线后实现转接方法
 */
public class Adapter implements NetToUsb {

    private Adapt adapt;

    public Adapter(Adapt adapt) {
        this.adapt = adapt;
    }

    @Override
    public void handleRequest() {
        adapt.request();
    }
}

上网

/**
 * 上网,支持用户热插拔,并支持同一个适配器选择不同的网线
 */
public class Test {
    public static void main(String[] args) {
        Computer computer = new Computer();
        Adapt1 adapt = new Adapt1();
        Adapter adapter = new Adapter(adapt);
        computer.net(adapter);

        Computer computer2 = new Computer();
        Adapt2 adapt2 = new Adapt2();
        Adapter adapter2 = new Adapter(adapt2);
        computer2.net(adapter2);
    }
}

参考总结

image.png

image.png