java设计模式——适配器模式

一. 定义与类型

定义:将一个类的接口转换成客户期望的另一个接口,使原本不兼容的类可以一起工作

类型:结构性

二. 使用场景

(1) 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)

(2) 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案

三. 优缺点

优点:

  (1) 能提高类的透明性和复用,现有的类复用但不需要改变

  (2) 目标类和适配器类解耦,提高程序扩展性

  (3) 符合开闭原则

缺点:

  (1) 适配器编写过程需要全面考虑,可能会增加系统的复杂新

  (2) 增加系统代码可读的难度

四. 适配器—扩展

对象适配器:通过组合,优先先择组合

类适配器:通过继承

五. 相关设计模式

适配器模式和外观模式:

(1) 它们都是对现有的类,现存的系统封装。

(2) 适配器是使用已有的接口,让两个或多个已有的接口协同工作,外观模式定义新的接口,在现有系统中提供一个更为方便的访问入口。

(3) 如果非要把外观模式也称之为适配,那它们最大的区别就是适配的力度不同。外观模式是适配整个子系统,所针对的对象力度更大。

六. Coding

类适配器:

替换目标方法的适配的方法

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:01
 **/
public class Adaptee {
    public void AdapteeRequest() {
        System.out.println("被适配者的方法");
    }
}

目标接口:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:02
 **/
public interface Target {
    void request();
}

目标方法:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:03
 **/
public class ConcreteTarget implements Target {
    public void request() {
        System.out.println("ConcreteTarget目标方法");
    }
}

适配方法:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:03
 **/
public class Adapter extends Adaptee implements Target {
    public void request() {
        //...可以加上逻辑
        super.AdapteeRequest();
        //...可以加上逻辑
    }
}

应用层:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:05
 **/
public class Test {
    public static void main(String[] args) {
        Target target = new ConcreteTarget();
        target.request();
        Target adapterTarget = new Adapter();
        adapterTarget.request();
    }
}

结果:

java设计模式——适配器模式

对象适配器:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:07
 **/
public class Adaptee {
    public void AdapteeRequest() {
        System.out.println("被适配者的方法");
    }
}
/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:02
 **/
public interface Target {
    void request();
}
/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:03
 **/
public class ConcreteTarget implements Target {
    public void request() {
        System.out.println("ConcreteTarget目标方法");
    }
}
/**
 * @program: designModel
 * @description: 通过组合的方式,把具体实现request的方法委托给Adaptee来实现
 * @author: YuKai Fan
 * @create: 2019-02-11 16:03
 **/
public class Adapter implements Target {
    private Adaptee adaptee = new Adaptee();
    public void request() {
        //...
        adaptee.AdapteeRequest();
        //...
    }
}
/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:05
 **/
public class Test {
    public static void main(String[] args) {
        Target target = new ConcreteTarget();
        target.request();

        Target adapterTarget = new Adapter();
        adapterTarget.request();
    }
}

从上面的代码可以看出,类适配器与对象适配器主要是在适配的过程,类适配器是通过继承,而对象适配器是通过组合。

用一个业务场景来体现对象适配器模式,

 adaptee被适配的方法:

/**
 * @program: designModel
 * @description: 220v的交流电
 * @author: YuKai Fan
 * @create: 2019-02-11 16:13
 **/
public class AC220 {
    public int outputAC220V() {
        int output = 220;
        System.out.println("输出交流电" + output + "V");
        return output;
    }
}

 目标方法的接口:

/**
 * @program: designModel
 * @description: 目标:5v直流电
 * @author: YuKai Fan
 * @create: 2019-02-11 16:16
 **/
public interface DC5 {
    int outputDC5V();
}

适配方法,将220v交流电,适配为5v直流电:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:17
 **/
public class PowerAdapter implements DC5 {
    private AC220 ac220 = new AC220();

    public int outputDC5V() {
        int adapterInput = ac220.outputAC220V();

        //变压器...
        int adapterOutput = adapterInput/44;

        System.out.println("使用PowerAdapter输入AC:" + adapterInput + "V" + ",输出DC:" + adapterOutput);
        return adapterOutput;
    }
}

 应用层:

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-11 16:19
 **/
public class Test {
    public static void main(String[] args) {
        DC5 dc5 = new PowerAdapter();
        dc5.outputDC5V();
    }
}

 结果:

java设计模式——适配器模式

UML类图:

java设计模式——适配器模式

七. 源码分析

jdk中的xmlAdapter

java设计模式——适配器模式

Spring AOP中的AdvisorAdapter的实现方法

java设计模式——适配器模式

Spring-data-jpa中的JpaVendorAdapter的相关实现类

SpringMVC中的HandlerAdapter的相关实现,

SpringMVC的核心控制器DispatcherServlet