适配器模式

适配器模式是作为两个不兼容的接口之间的桥梁。如插座是两脚插座不能给电脑间接应用,因为电脑的电源线根本都是三脚的,于是咱们应用一个插线板连贯电脑和插座,这个插线板就是一个适配器。

代码演示:

两脚插头接口:

/** * @author objcfeng * @description 两脚插头 * @date 2020/12/15 */public interface TwoPlug {    void useElectricity();}

三脚插头接口:

//三脚插头public interface ThreePlug {    void useElectricity();}

插座(须要传入两脚插头的实现类能力开始供电并调用两脚插头的办法):

/** * @author objcfeng * @description 两脚插座 * @date 2020/11/9 */public class Socket {    /**     * Description: 应用插座     * @param twoPlugThings 只能反对两脚插头     */    public void useSocket(TwoPlug twoPlugThings){        System.out.println("插座开始供电");        twoPlugThings.useElectricity();    }}

电脑(三脚插头实现类):

/** * @author objcfeng * @description 电脑三脚插头 * @date 2020/11/9 */public class Computer implements ThreePlug {    @Override    public void useElectricity() {        System.out.println("电脑开始用电...");    }}

能够看出,当初电脑无奈应用电,因为插座的useSocket办法须要传入一个两脚插头的类型,而电脑是三脚插头的类型。咱们再创立一个适配器类以适配插座和电脑。

适配器类:

/** * @author objcfeng * @description 适配器 * @date 2020/12/14 */public class Adapter implements TwoPlug {    private Computer computer;    public Adapter(Computer computer) {        this.computer = computer;    }    @Override    public void useElectricity() {        computer.useElectricity();    }}

要害是:

适配器类实现了两脚插头,这样就能传入useSocket办法了,而后适配器类应用构造方法组合进一个Computer,并在useElectricity办法调用Computer的useElectricity办法,这样插座类调用适配器类的useElectricity办法就是调用了电脑的useElectricity办法,电脑就能用电了。

测试:

public class Main {    public static void main(String[] args) {        Computer computer = new Computer();        Socket socket = new Socket();        socket.useSocket(new Adapter(computer));    }}

输入:

插座开始供电电脑开始用电...

为什么应用适配器?

当现有的接口无奈满足零碎的需要须要引入新的接口,然而新的接口不能间接被零碎间接应用时,能够应用适配器。例如,

新建一个Thread类,来执行工作,Thread结构可接管的参数有

咱们个别传入一个Runnable类型的工作来执行工作,如下

        Runnable task = () -> {            //执行工作           };        new Thread(task).start();

当初咱们须要获取task执行完工作的返回值,或者获取到工作执行中产生的异样,该怎么做呢?

一种办法是咱们能够定义一个线程平安的List来接管工作执行的后果和工作抛出的异样;然而更好的办法是,

  1. 创立一个新的接口Callable,它具备返回值并且会抛出异样。

    public interface Callable<V> {    /**     * 计算结果,或在无奈计算时引发异样。      * @return 计算结果     * @throws 异样     */    V call() throws Exception;}
  2. 创立一个适配器类用来适配Runnable和Callable

    适配器接口

    public interface RunnableFuture<V> extends Runnable, Future<V> {    /**     * Sets this Future to the result of its computation     * unless it has been cancelled.     */    void run();}

    而FutureTask实现了这个接口,所以咱们应用这个类来适配Thread和Callable

    应用:

            Callable<String> task = () ->"Hello";        FutureTask<String> futureTask = new FutureTask<>(task);        new Thread(futureTask).start();        String str = null;        try {            //获取工作的返回值            str = futureTask.get();        } catch (InterruptedException | ExecutionException e) {            //解决工作执行中抛出的异样        }        System.out.println(str);