1、适配器模式定义
将一个类的接口适配成用户所期待的。它是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。类似插座和电脑转接头。
2、适配器模式结构图
如图所示,typeC接口的手机(被适配对象Adaptee)不能直接访问VGA接口的投影仪(访问目标target)。需要通过typeC转VGA的转接头(适配器Adapter)才能将手机内容投屏到投影仪上
3、使用场景
手机想要投影到投影仪上,由于手机是typeC接口,投影仪是VGA接口。不能直接投影,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。
4、适配器模式在使用场景的具体实现
图: typec转vga/hdm转换器
如图所示,这有一个适配器,一号口是typec口,二号口是vga口,只有将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接,实现手机屏幕投影到投影仪上的任务。涉及的物品有:手机、适配器、投影仪。
4.1 定义一个手机,它有个typec口,这是视频源。
package com.dolphin.adapter;
public class Phone {
public void typecPhone() {
System.out.println("信息从typec扣的手机输出");
}
}
4.2 定义一个vga接口
package com.dolphin.adapter;
public interface Vga {
void vgaInterface();
}
4.3 实现一个适配器,适配器实现方式分三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
4.3.1 类的适配器模式
原理:通过继承特性来实现适配器功能。
package com.dolphin.adapter;
public class Typec2Vga1 extends Phone implements Vga {
@Override
public void vgaInterface() {
super.typecPhone();
System.out.println("接收到Type-c扣信息,信息转换成VGA接口中");
System.out.println("信息已转换成VGA接口,显示屏可以对接");
}
}
4.3.2 对象的适配器模式
原理:通过组合方式来实现适配器功能。
package com.dolphin.adapter;
public class Typec2Vga2 implements Vga {
private Phone phone;
public Typec2Vga2(Phone phone) {
this.phone = phone;
}
@Override
public void vgaInterface() {
phone.typecPhone();
System.out.println("接收到Type-c扣信息,信息转换成VGA接口中");
System.out.println("信息已转换成VGA接口,显示屏可以对接");
}
}
4.3.3 接口的适配器模式
原理:借助抽象类来实现适配器功能。
定义三个接口
package com.jstao.adapter;
/**
* 定义接口
*
*/
public interface Target {
void typec();
void typec2vga();
void typec2hdmi();
}
定义一个抽象类
package com.jstao.adapter;
/**
* 定义一个抽象类
*
*/
public abstract class Adapter implements Target{
public void typec() { }
public void typec2vga() { }
public void typec2hdmi() { }
}
实现一个VGA适配器
package com.jstao.adapter;
/**
*
* 实现一个VGA适配器,同理还可以实现一个HDMI适配器
* 适配器实现方式有三种,这是第三种实现方式。
*
*/
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("显示屏对接适配器,手机成功投影到显示屏!");
}
}
测试结果:
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接口的适配器模式。