将一个类的接口转成客户期望的另外一个接口。适配器模式使得原本由于接口不匹配而不能一起工作的那些类可以一起工作。
适配器模式就像旅行插座转换器(图1)、Type-c转VGA转接口(图4)一样。
图1. 图片来源网络
图2. 图片来源网络
去过香港迪拜等的同学都知道,那边用的插座跟我们不一样,他们的插座需要如图2第1面所示的插头,而我们常用的插座类似第2面。因此我们的笔记本电脑,手机在当地不能直接充电。所以就需要一个插座转换器,转换器第1面插入当地的插座,第2面供我们充电,这样使得我们的插头在当地能使用。Type-c转VGA转接口也是一样的道理。
图3. 适配模式结构图 来源网络
如图所示,Client不能直接访问Adaptee。Adapter是适配器,它将Adaptee转换成Client能访问的接口。所以通过适配器Adapter,用户端就可以访问Adaptee。
手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。
图4. typec转vga/hdm转换器
如图所示,这有一个适配器,一号口是typec口,二号口是vga口,只有将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接,实现手机屏幕投影到投影仪上的任务。涉及的物品有:手机、适配器、投影仪。
4.1 定义一个手机,它有个typec口,这是视频源。
4.2 定义一个vga接口
4.3 实现一个适配器,适配器实现方式分三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
4.3.1 类的适配器模式
原理:通过继承特性来实现适配器功能。
4.3.2 对象的适配器模式
原理:通过组合方式来实现适配器功能。
4.3.3 接口的适配器模式
原理:借助抽象类来实现适配器功能。
定义三个接口
定义一个抽象类
实现一个VGA适配器
4.4 定义一个显示屏,用来测试上面实现的三个适配器
4.5 测试结果
图5. 结果输出图
可以看到,得到的结果都一样,但是三种适配器的实现的方式却不相同。
5.1 适配器模式在源码中的应用:
(1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。
(2)mybatis源码日志模块用到对象适配器模式。
5.1 适配器模式将一个接口转为另外一个接口。它有三种实现方式:
(1)当希望将一个类转换为满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可,例如4.3.1。
(2) 当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Typec2Vga2 类,持有原类的一个实例,在Typec2Vga2 类的方法中,调用实例的方法就行,例如4.3.2对象的适配器模式。
(3)当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可,例如4.3.3接口的适配器模式。