设计模式——适配器模式
初探设计模式——适配器模式
一、什么是适配器?
适配器在我们生活中其实非常的常见,比如电源适配器,我们生活用电是220v电压,而我们的手机在充电时,是承受不了220v的电压的,只能接收5v,9v,12v这种较低的电压来充电,那么很显然我们220v的电压手机是接受不了的,不兼容的,我们的手机充电器,其实是电源适配器,它将我们的生活用电220v电压转换为 5v,9v,12v等手机可以接收的电压,那么这个电源适配器,相当于一个电压转换器,将两种不兼容的电压接口,通过它的转换,变得兼容,可以一起工作,相当于一个接口转换器。
二、什么是适配器模式?
将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作
结合我们的生活实例理解,有一台显示器只有VGA接口,它通过VGA接口接收图像信号,通过电子荧屏显示出图像。一块只有HDMI接口的显示卡,它通过HDMI接口将图像数据输出。显示器拥有VGA接口,显示卡拥有HDMI接口,两者彼此接口不同,它们两者无法在一起工作,但此时如果有一个HDMI转VGA的转换器,将显卡输出的HDMI信号转换为VGA信号,那么显示器就可以利用该VGA信号进行图像显示。
三、适配器模式类型
适配器模式类型分为两种
- 对象适配器模式
在对象适配器模式中,适配器容纳一个它包裹的类的实例,适配器调用被包裹的对象的物理实体。
-
类适配器模式
在这种适配器模式下,适配器继承自己实现的类(一般指多继承(java中通过继承+实现接口的方式来实现))
四、示例演示
看到上面的适配器模式,可能还有些似懂非懂的感觉,接下来我们将用示例来讲解这两种模式。
我们的示例就是,一台只拥有VGA接口的显示器,和只拥有HDMI接口的显示卡。
对象适配器模式示例
VGA接口
public interface VGAInterface {
//使用VGA信号输出
public void showWithVGASignal();
}
VGA线,实现了VGA接口
public class VGALine implements VGAInterface {
@Override
public void showWithVGASignal() {
System.out.println("使用VGA信号输出");
}
}
Monitor,显示器类,显示器只有一个VGA接口
public class Monitor{
VGAInterface vgaInterface;
public Monitor(VGAInterface vgaInterface1)
{
vgaInterface = vgaInterface1;
}
public void setVgaInterface(VGAInterface vgaInterface) {
this.vgaInterface = vgaInterface;
}
public void show()
{
/*
显示器的show方法,调用VGA接口的showWithVGASignal方法
*/
vgaInterface.showWithVGASignal();
}
}
测试一下
public class Run {
public static void main(String[] args) {
VGALine vgaLine = new VGALine(); //一条VGA接口的线
Monitor monitor = new Monitor(vgaLine); //接在了显示器的VGA接口上
monitor.show(); //显示器显示
}
}
输出结果
这里和我们的初期预想结果一样,显示器的VGA接口接上了VGA线,使用VGA信号显示了图像。那么我们如何让显示器使用HDMI信号呢?
HDMI接口
public interface HDMIIntertface {
//使用HDMI信号显示
public void showWithHDMISignal();
}
HDMI线,实现了HDMI接口
public class HDMILine implements HDMIIntertface {
@Override
public void showWithHDMISignal() {
System.out.println("使用HDMI信号输出");
}
}
很显然有HDMI接口的线,但是是不能用在显示器的VGA接口上的,所以我们需要适配器
适配器,实现了VGA接口,可以和显示器VGA接口对接,该适配器内还包含了一个HDMI接口的对象
在实现适配器的时候就要个要求:
- 适配器必须实现原有接口
- 适配器对象的成员中必须有新接口的引用,当调用旧接口时,将这个调用委托给实现了新接口的对象来处理
//适配器VideoAdapter类实现了VGAInterface
public class VideoAdapter implements VGAInterface {
//适配器中有新接口的引用,HDMI接口引用
HDMIIntertface hdmiIntertface;
public VideoAdapter(HDMIIntertface hdmiIntertface)
{
this.hdmiIntertface = hdmiIntertface;
}
@Override
public void showWithVGASignal() {
/*
当调用旧接口时,将这个调用委托给实现了新接口的对象来处理,也就是交给了hdmiIntertface来处理
*/
hdmiIntertface.showWithHDMISignal();
}
}
接下来我们再测试一下:
public class Run {
public static void main(String[] args) {
//一条HDMI线
HDMILine hdmiLine = new HDMILine();
//一个适配器,该适配器和HDMI相连
VideoAdapter videoAdapter = new VideoAdapter(hdmiLine);
//将显示器的VGA接口,和适配器的VGA接口相连
Monitor monitor = new Monitor(videoAdapter);
//显示器显示
monitor.show();
}
}
输出结果:
我们可以看到,最后显示器成功使用HDMI接口的信号输出图像,因为VideoAdapter,适配器实现了老接口VGA接口,又包含了新接口HDMI接口,所以可以同时和显示器的VGA接口相连,又可以和HDMi接口相连,所以就实现了将从HDMI接口输出的数据,经过它的转换,又从和显示器相连的VGA接口输出,正好达到了我们之前说的适配器就是一个接口转换器,使得因接口不兼容而不能在一起工作的类能在一起工作。
类适配器模式
适配器继承自己实现的类(一般指多继承(java中通过继承+实现接口的方式来实现))
那么根据刚才的示例,我们有
- VGA接口 VGAInterface
- HDMI接口 HDMIInterface
- 具有VGA接口的显示器 Monitor
- VGALine
- HDMILine
下面我们来用类适配器模式来实现一个VideoAdapter2
public class VideoAdapter2 extends HDMILine implements VGAInterface {
/*
该类继承自HDMILine这个需要**被适配**的类,然后又实现了VGAInterface
*/
@Override
public void showWithVGASignal() {
showWithHDMISignal();
}
}
再次测试一下:
public class Run {
public static void main(String[] args) {
//创建类适配器
VideoAdapter2 adapter2 = new VideoAdapter2();
//给显示器设置VGA接口(设置适配器)
Monitor monitor = new Monitor(adapter2);
//显示
monitor.show();
}
}
测试结果:
VideoAdapter2继承自HDMILine这个需要被适配的类,同时又实现了VGA接口,所以和上面的结果一样,都可以发挥这个适配器的接口转换功能。所以我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。
以上就是就是我自己对于适配器模式的一些理解和总结,如果错误,请于指正。
下一篇: 基于决策树的分类预测