Java设计模式——结构性模式——适配器模式(ADAPTER)

适配器模式(Adapter)把一个类的接口变换成客户端所期待的另一种接口,从而 

使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

两种适配器模式

根据适配器类与适配者类的关系不同,适配器模式可分为 类适配器 和 对象适配器两种,类适配器模式通过重继承对一个接口与另一个接口进行匹配,而对象适 配器则是 引用 关系。

类适配器

Java设计模式——结构性模式——适配器模式(ADAPTER)

类适配器的三个角色

  • 目标接口(Target):客户所期待的接口,目标是接口
  • 需要适配的类(Adaptee):需要适配的类或适配者类;
  • 适配器(Adapter):实现了抽象目标类接口Target,并继承了适配者类Adaptee

对象适配器

Java设计模式——结构性模式——适配器模式(ADAPTER)

对象适配器的三个角色

  • 目标接口(Target):客户所期待的接口,可以是具体的或抽象的类,也可以是接口
  • 需要适配的类(Adaptee):需要适配的类或适配者类;
  • 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口;

代码

我们想象一种实际生产环境中会遇到的一种场景:

曾经有一个正常使用的接口,随着项目迭代,原本的实现已经不再满足现在的需求,需要调用另外一个已有的方法来完成。

public interface Target {

    void targetMethod();
}
public class TargetImpl implements Target {
    public void targetMethod() {
        System.out.println("最初TargetImpl实现的targetMethod(),可是逐渐的不再适用");
    }
}

public class Adaptee {

    public void doSomething(){
        System.out.println("Adaptee:doSomething");
    }
}
上面是原本的接口,已经不再适用。为了完成新的需求,需要使用Adaptee类中的doSomething()方法。那么,如何在客户端不更改代码的情况下顺利的用新的方法替换掉原本的实现呢?这个时候就需要用到适配器模式了。

类适配器模式

public class AdapterA extends Adaptee implements Target{
    public void targetMethod() {
        System.out.println("1.类适配器,采用继承的方式实现");
        doSomething();
    }
}
新建一个类适配器AdapterA,继承了需要适配的类Adaptee,同时实现目标接口Target。

测试方法:

public static void main(String[] args) {
    //最初的实现方法,在项目迭代过程中逐渐不再适用,需要新的逻辑来实现这个接口
    Target target = new TargetImpl();
    target.targetMethod();
    System.out.println("~~~~~~~~~~~~~~~~~~~~");

    //1.类适配器,采用继承的方式实现
    Target adapterA = new AdapterA();
    adapterA.targetMethod();
}
测试结果:

最初TargetImpl实现的targetMethod(),可是逐渐的不再适用
~~~~~~~~~~~~~~~~~~~~
1.类适配器,采用继承的方式实现
Adaptee:doSomething


 对象适配器模式

public class AdapterB implements Target{

    private Adaptee adaptee = new Adaptee();

    public void targetMethod() {
        System.out.println("2.对象适配器,采用对象组合的方式实现");
        adaptee.doSomething();
    }
}
创建一个对象适配器AdapterB实现目标接口Target,通过对象组合的方式获得一个适配的类Adaptee的引用,然后使用该引用中的方法。

测试方法:

public static void main(String[] args) {
    //最初的实现方法,在项目迭代过程中逐渐不再适用,需要新的逻辑来实现这个接口
    Target target = new TargetImpl();
    target.targetMethod();

    System.out.println("~~~~~~~~~~~~~~~~~~~~");

    //2.对象适配器,采用对象组合的方式实现
    Target adapterB = new AdapterB();
    adapterB.targetMethod();
}

测试结果:

最初TargetImpl实现的targetMethod(),可是逐渐的不再适用
~~~~~~~~~~~~~~~~~~~~
2.对象适配器,采用对象组合的方式实现
Adaptee:doSomething