Skip to content

12 适配器模式

Landy.Liu edited this page May 19, 2019 · 1 revision

代码参见 design-patterns-basic 工程中的adapter包。

12.1 概念

适配器模式是一种适配中间件的模式,适配接口(类)和被适配接口(类)之间是没有层次关系的。

12.2 实现方式

适配器模式目前有三种实现方式,类适配器模式、对象适配器模式、接口适配器模式。

12.2.1 类适配器模式

通过继承来实现类适配器功能,当我们要访问的接口A中没有想要的方法,而在另一个接口B中有此方法,但是又不能改变访问接口A,这时候我们就可以定义一个适配器来适配两个接口。这个适配器要实现我们的接口A,然后继承接口B的实现类即可。

public class PS2ToUsberAdapter extends Usber implements PS2 {
    @Override
    public boolean isPs2() {
        System.out.println("PS2接口转化为了USB接口");
        return isUsb();
    }
}

12.2.2 对象适配器模式

通过组合来实现适配器功能,当我们要访问的接口A中没有想要的方法,而在另一个接口B中有此方法,但是又不能改变访问接口A,这时候我们就可以定义一个适配器来适配两个接口。这个适配器要实现我们的接口A,而且要引入成员变量接口B的实例,再定义一个带参数的构造方法(参数类型就是接口B),再在接口A中的方法中调用成员变量对象的方法。

public class PS2ToUsberAdapter implements PS2 {

    private USB usb;

    public PS2ToUsberAdapter(USB usb) {
        this.usb = usb;
    }

    @Override
    public boolean isPs2() {
        System.out.println("PS2接口转化为了USB接口");
        return usb.isUsb();
    }
}

12.2.3 接口适配器模式

通过抽象类来实现适配器功能,当存在这样一个接口,其中定义了N多的方法,而我们现在却只想使用其中的一个到几个方法,如果我们直接实现接口,那么我们要对所有的方法进行实现,哪怕我们仅仅是对不需要的方法进行置空(只写一对大括号,不做具体方法实现)也会导致这个类变得臃肿,调用也不方便,这时我们可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空,那么我们在创建抽象类的继承类,而且重写我们需要使用的那几个方法即可。

public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener {
    /**
     * {@inheritDoc}
     */
    public void mouseClicked(MouseEvent e) {}

    /**
     * {@inheritDoc}
     */
    public void mousePressed(MouseEvent e) {}

    /**
     * {@inheritDoc}
     */
    public void mouseReleased(MouseEvent e) {}

    /**
     * {@inheritDoc}
     */
    public void mouseEntered(MouseEvent e) {}

    /**
     * {@inheritDoc}
     */
    public void mouseExited(MouseEvent e) {}

    /**
     * {@inheritDoc}
     * @since 1.6
     */
    public void mouseWheelMoved(MouseWheelEvent e){}

    /**
     * {@inheritDoc}
     * @since 1.6
     */
    public void mouseDragged(MouseEvent e){}

    /**
     * {@inheritDoc}
     * @since 1.6
     */
    public void mouseMoved(MouseEvent e){}
}

12.3 适用场景

12.3.1 类适配器与对象适配器模式

类适配器与对象适配器的使用场景一致,仅仅是实现手段稍有区别,二者主要用于如下场景:

  • 想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
  • 一个类想将其设计为可重用的类(可被多处访问),我们可以创建适配器来将这个类来适配其他没有提供合适接口的类。

以上两个场景其实就是从两个角度来描述一类问题,那就是要访问的方法不在合适的接口里,一个从接口出发(被访问),一个从访问出发(主动访问)。

12.3.2 接口适配器模式

想要使用接口中的某个或某些方法,但是接口中有太多方法,我们要使用时必须实现接口并实现其中的所有方法,可以使用抽象类来实现接口,并不对方法进行实现(仅置空),然后我们再继承这个抽象类来通过重写想用的方法的方式来实现。这个抽象类就是适配器。