将一个类的接口转成客户指望的另一个接口。适配器模式使得本来因为接口不匹配而不能一块儿工做的那些类能够一块儿工做。html
适配器模式就像旅行插座转换器(图1)、Type-c转VGA转接口(图4)同样。java
图1. 图片来源网络设计模式
图2. 图片来源网络网络
去过香港迪拜等的同窗都知道,那边用的插座跟咱们不同,他们的插座须要如图2第1面所示的插头,而咱们经常使用的插座相似第2面。所以咱们的笔记本电脑,手机在当地不能直接充电。因此就须要一个插座转换器,转换器第1面插入当地的插座,第2面供咱们充电,这样使得咱们的插头在当地能使用。Type-c转VGA转接口也是同样的道理。mybatis
图3. 适配模式结构图 来源网络ide
如图所示,Client不能直接访问Adaptee。Adapter是适配器,它将Adaptee转换成Client能访问的接口。因此经过适配器Adapter,用户端就能够访问Adaptee。post
手机想要投影到投影仪上,因为手机是Type-c接口,投影仪是VGA接口。不能直接投影,须要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。测试
图4. typec转vga/hdm转换器this
如图所示,这有一个适配器,一号口是typec口,二号口是vga口,只有将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接,实现手机屏幕投影到投影仪上的任务。涉及的物品有:手机、适配器、投影仪。url
4.1 定义一个手机,它有个typec口,这是视频源。
package com.jstao.adapter; /** * @author jstao * 定义一个手机Phone,它有一个Typec接口。 * */ public class Phone { public void typecPhone() { System.out.println("信息从Typec口的手机输出。"); } }
4.2 定义一个vga接口
package com.jstao.adapter; /** * @author jstao * 定义一个VGA接口。 * */ public interface Vga { void vgaInterface(); }
4.3 实现一个适配器,适配器实现方式分三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
4.3.1 类的适配器模式
原理:经过继承特性来实现适配器功能。
package com.jstao.adapter; /** * * 实现一个Type-c转VGA适配器, * 适配器实现方式有三种,这是第一种实现方式。 * @author jstao * */ public class Typec2Vga1 extends Phone implements Vga{ @Override public void vgaInterface() { // TODO Auto-generated method stub typecPhone(); System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏能够对接。"); } }
4.3.2 对象的适配器模式
原理:经过组合方式来实现适配器功能。
package com.jstao.adapter; /** * * 实现一个Type-c转VGA适配器, * 适配器实现方式有三种,这是第二种实现方式。 * @author jstao * */ public class Typec2Vga2 implements Vga{ private Phone phone; public Typec2Vga2(Phone phone) { // TODO Auto-generated constructor stub this.phone = phone; } @Override public void vgaInterface() { // TODO Auto-generated method stub if(phone != null) { phone.typecPhone(); System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏能够对接。"); } } }
4.3.3 接口的适配器模式
原理:借助抽象类来实现适配器功能。
定义三个接口
package com.jstao.adapter; /** * 定义接口 * @author jstao * */ public interface Target { void typec(); void typec2vga(); void typec2hdmi(); }
定义一个抽象类
package com.jstao.adapter; /** * 定义一个抽象类 * @author jstao * */ public abstract class Adapter implements Target{ public void typec() { } public void typec2vga() { } public void typec2hdmi() { } }
实现一个VGA适配器
package com.jstao.adapter; /** * * 实现一个VGA适配器,同理还能够实现一个HDMI适配器 * 适配器实现方式有三种,这是第三种实现方式。 * @author jstao * */ public class VgaAdapter extends Adapter{ public void typec() { System.out.println("信息从Typec口的手机输出。"); } public void typec2vga() { System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏能够对接。"); } }
4.4 定义一个显示屏,用来测试上面实现的三个适配器
package com.jstao.adapter; /** * 定义一个显示屏 * 与适配器对接 * @author jstao * */ public class Screen { public static void main(String[] args) { //第一种适配器用法 System.out.println("-------------第一种适配器------------"); Vga vga = new Typec2Vga1(); vga.vgaInterface();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); //第二种适配器用法 System.out.println("-------------第二种适配器------------"); Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone()); typec2Vga1.vgaInterface();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); //第三种适配器用法 System.out.println("-------------第三种适配器------------"); VgaAdapter vgaAdapter = new VgaAdapter(); vgaAdapter.typec(); vgaAdapter.typec2vga();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); } }
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接口的适配器模式。
你的支持也是个人动力,最后笔记对你有用,别忘了点赞支持下哦。