第9章 适配器(Adapter)模式
如果你去美国出差,你带的笔记本电脑插头是中国标准的,就没办法直接连接他们的电源插孔。一般,你不会为笔记本电脑再去买一个新的可以连接美国插座的电源,往往我们会买一个插座转换器,用这个转换器连接美国插座,而你的插头连接这个转换器就可以了。
现实世界中,我们有数不尽的适配器,例如交直流转换器、PS2-USB的鼠标/键盘接口转换线,还有在汽车上用于给手机、iPod等充电用的电源转换器。在编程世界,我们也经常碰到类似的情况:我们需要把一个接口转换成另外接口,以此使得客户对象能够继续使用这类对象而不需任何改变,我们把这个转换类就叫做适配器。
本章我们将讨论适配器在面向对象编程中的应用,主要包含如下内容。
适配器模式。
类适配器和双向适配器。
和代理模式的比较。
9.1 打桩
我们这里以打桩为场景来介绍适配器模式。我们需要建造一幢高楼,需要打方形桩,这里抽象出一个IPeg接口,SquarePeg是它的实现类,UML静态类图如图9-1所示。
图9-1
我们来编写它们的模拟代码,如下所示。
现在我们还需要打圆形桩,实现圆形桩不是一件容易的事情,所幸的是,我找到了一个RoundPeg类,它实现了IRoundPeg接口的insertIntoRoundHole()的方法。UML静态类图如图9-2所示。
图9-2
模拟代码如下所示。
尽管RoundPeg类实现了insertIntoRoundHole()的逻辑,但是客户对象不能像使用SquarePeg对象一样直接使用RoundPeg对象,因为它们的接口不一致,RoundPeg的接口不是IPeg。
现在轮到适配器模式上场了,我们为此撰写一个适配器类,使它实现IPeg接口,但是它除了把insertIntoHole()请求转发给IRoundPeg的insertIntoRoundHole()方法处理之外,自己不做任何额外的逻辑,不难画出UML静态类图,如图9-3所示。
图9-3
IPeg接口是我们的Target(目标)接口,IRoundPeg是Adaptee接口(被适配的接口),而RoundPegAdapter就是Adapter类(适配器类)。
适配器的代码非常简单,如下所示。