适配器模式(Adapter)通常也被称为转换器,顾名思义,它一定是进行适应与匹配工作的物件。当一个对象或类的接口不能匹配用户所期待的接口时,适配器就充当中间转换的角色,以达到兼容用户接口的目的,同时适配器也实现了客户端与接口的解耦,提高了组件的可复用性。
提示:以下是本篇文章正文内容,下面案例可供参考
对象是多样化的,对象之间通过信息交换,也就是互动、沟通,世界才充满生机,否则就是死水一潭。人类最常用的沟通方式就是语言,两个人对话时,一方通过嘴巴发出声音,另一方则通过耳朵接收这些语言信息,所以嘴巴和耳朵(接口)必须兼容同一种语言(参数)才能达到沟通的目的。试想,我们跟不懂中文的人讲中文一定是徒劳的,因为对方根本无法理解我们在讲什么,更不要说人类和动物对话了,接口不兼容的结果就是对牛弹琴。
对象是多样化的,对象之间通过信息交换,也就是互动、沟通,世界才充满生机,否则就是死水一潭。人类最常用的沟通方式就是语言,两个人对话时,一方通过嘴巴发出声音,另一方则通过耳朵接收这些语言信息,所以嘴巴和耳朵(接口)必须兼容同一种语言(参数)才能达到沟通的目的。试想,我们跟不懂中文的人讲中文一定是徒劳的,因为对方根本无法理解我们在讲什么,更不要说人类和动物对话了,接口不兼容的结果就是对牛弹琴,如图10-1所示。
举一个生活中常见的实例,我们新买了一台电视机,其电源插头是两相的,不巧的是墙上的插孔却是三相的,这时电视机便无法通电使用。我们以代码来重现这个场景。
public interface TriplePin {// 参数分别是火线、零线、地线public void electrify(int l, int n, int e);
}
说明:
public interface DualPin {// 这里没有地线public void electrify(int l, int n);
}
说明:
客户端类代码干净、利落,我们将构造出来的女生类实例作为参数传给化妆品装饰器类的构造方法,这就好像为女生外表包裹了一层化妆品一样,对象结构非常生动、形象。接着,我们调用的是化妆品的展示方法show(),运行结果立竿见影,除女生自己的素颜展示结果之外还加上了额外的化妆效果。
public class TV implements DualPin {@Overridepublic void electrify(int l, int n) {System.out.println("火线通电:" + l + ",零线通电:" + n);System.out.println("电视开机");}
}
说明:
代码很简单,而目前我们面临的问题是,墙上的接口是三相插孔,而电视机实现的是两相插孔,二者无法匹配,如代码所示,客户端无法将两相插头与三相插孔完成接驳。
public class Client {public static void main(String[] args) {TriplePin triplePinDevice = new TV(); //接口不兼容,此处保持类型不匹配}
}
针对接口不兼容的情况,可能有人会提出比较极端的解决方案,就是把插头掰弯强行适配,若是三相插头接两相插孔的话,就把零线插针拔掉。虽然目的达到了,但经过这么一番暴力修改,插头也无法再兼容其原生接口了,这显然是违背设计模式原则的。为了不破坏现有的电视机插头,我们需要一个适配器来做电源转换,有了它我们便可以顺利地把电视机两相插头转接到墙上的三相插孔中了。
public class Adapter implements TriplePin {private DualPin dualPinDevice;//创建适配器时,需要把两插设备接入进来public Adapter(DualPin dualPinDevice) {this.dualPinDevice = dualPinDevice;}//适配器实现的是目标接口@Overridepublic void electrify(int l, int n, int e) {//调用被适配设备的两插通电方法,忽略地线参数edualPinDevice.electrify(l, n);}
}
说明:
public class Client {public static void main(String[] args) {DualPin dualPinDevice = new TV(); //构造两插电视机TriplePin triplePinDevice = new Adapter(dualPinDevice); //适配器接驳两端triplePinDevice.electrify(1, 0, -1); //此处调用的是三插通电的标准}
}
输出结果:
火线通电:1,零线通电:0
电视开机
注意:
除了上面所讲的“对象适配器”,我们还可以用“类适配器”实现接口的匹配,这是实现适配器模式的另一种方式。顾名思义,既然是类适配器,那么一定是属于某个类的“专属适配器”,也就是在编码阶段已经将被匹配的设备与目标接口进行对接了。我们继续之前的例子,请参看代码。
//I/O流处理类的应用
File file = new File("/压缩包.zip");
ZipInputStream zipInputStream = new ZipInputStream(new BufferedInputStream(new FileInputStream(file))
);
说明:
public class Client {public static void main(String[] args) {TriplePin tvAdapter = new TVAdapter(); //电视机专属三插适配器插入三相插孔tvAdapter.electrify(1, 0, -1);}
}
输出结果:
火线通电:1,零线通电:0
电视开机
注意:
众所周知,反复修改代码的代价是巨大的,因为所有依赖关系都要受到牵连,这不但会引入更多没有必要的重构与测试工作,而且其波及范围难以估量,可能会带来不可预知的风险,结果得不偿失。适配器模式让兼容性问题在不必修改任何代码的情况下得以解决,其中适配器类是核心
上一篇:Windows及Kail安装配置
下一篇:7个硬核嵌入式C进阶要点!