跳至主要內容

适配器模式

fangzhipeng约 982 字大约 3 分钟

今天这一讲,我们主要讲解最常用到的适配器模式。

在程序中,经常需要新的项目中需要对老代码进行适配才能用。适配器模式就是将旧代码和新程序的中间的转换角色。举个现实例子,比如我们的MAC电脑需要连接USB接口的键盘,但是MAC电脑只有typec接口,这时我们需要一个拓展坞,需要把typec接口转换成USB接口,给键盘使用,如图所示:

image-20231101224648036

适配器模式类图

适配器模式的定义是:将类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作。

我们以拓展坞作为适配器将typec接口转换成usb接口为例进行讲解,它的UML图如下所示:

image-20231101223247880

从 UML 图中,我们可以看出适配器模式中包含三个关键角色:

  • 目标类Target, 适配器类即将要进行适配的抽象类或接口,比如TypeC接口;

  • 适配器类Adapter,是作为适配的中间类,它必须持有或者实现目标类和适配类的接口,比如拓展坞类实现了目标接口TypeC接口,持有适配者的类Keyboard;

  • 需要被适配器转换的对象 Adaptee, 比如图中的键盘(实现了USB接口)。

代码实现

需要被适配的接口USB接口:

public interface IUsb {

    void connect(int x, int y);
}

需要被适配的接口的实现类,比如案例中Keyboard:

public class Keyboard  implements IUsb{
    @Override
    public void connect(int x, int y) {
        System.out.println("keyborad 连上了usb接口");
    }
}

目标接口ITypeC:

public interface ITypeC {

    void connect(int x, int y,int z);
}

ExpansionDockAdapter(拓展坞适配器)实现了ITypeC的目标接口接口,ExpansionDockAdapter并持有需要被适配的IUsb接口,适配器只有同时实现或者持有目标接口和被适配的对象,才能进行适配工作:

public class ExpansionDockAdapter implements ITypeC{
    private IUsb iUsb;

    public ExpansionDockAdapter(IUsb iUsb) {
        this.iUsb = iUsb;
    }

    @Override
    public void connect(int x, int y, int z) {
        System.out.println("拓展坞将Typec接口转换成USB接口");
        iUsb.connect(x,y);
    }
}

最后,可以调用客户端对它们调用:

public class McClient {

    public static void main(String[] args) {
        Keyboard keyboard = new Keyboard();
        ExpansionDockAdapter adapter = new ExpansionDockAdapter(keyboard);
        System.out.println("mac连接typec");
        adapter.connect(1, 2, 3);
    }
}

使用适配器模式有什么收益

可能有很多人比较疑惑,如果在目标类中,新写一个方法就可以将需要适配的类进行转换。那么为什么还需要使用适配器模式呢?

  • 首先 ,是为了保持简单性,正如mac电脑一样,它只提供TypeC接口。由拓展坞去做USB或者是HDMI接口的转换。保证了MAC电脑对外接口的简单性。
  • 单一职责,不同的角色做不同的事,没有必要将多个事情给一个角色做完,这样代码会非常的臃肿,难以维护。
  • 可复用,将适配器这个角色进行高度抽象化,可以做到移植可复用

使用适配器模式有以下的优点:

  • 将目标类和适配的类解耦,引入一个适配器类兼容现有目标类,拓展新的适配者类功能,很好的避免了现有类和适配者类的耦合。

  • 单一职责,目标类和适配者类各司其职,互不干扰。

  • 满足里氏替换原则。 目标类和适配者类是通过适配器进行交互的,适配器类只要不影响目标类的接口功能,适配者类无论出现什么新功能,都很方便替换。

源码下载

方志朋_官方公众号
方志朋_官方公众号