适配器模式
适配器模式可用来在现有接口和不兼容的类之间进行适配。使用这种模式的对象又叫包装器,因为它们在用一个新的接口包装另一个对象。许多时候创建适配器对程序员和接口设计人员都有好处。在设计类的时候往往会遇到有些接口不能与现有API一同使用的情况。借助于适配器,你不用直接修改这些类也能使用它们。
适配器的特点
适配器可以被添加到现有代码中以协调两个不同的接口。如果现有代码的接口能很好地满足需要,那就可能没有必要使用适配器。但要是现有接口对于手头的工作来说不够直观或实现,那么可以使用适配器来提供一个更简洁或丰富的接口。
从表面上看,适配器模式很像门面模式。它们都要对别的对象进行包装并改变其呈现的接口。二者的差别在于它们如何改变接口。门面元素展现的是一个简化的接口,它并不提供额外的选择,而且有时为了方便完成常见任务它会做出一些假定。而适配器则要把一个接口转换为另一个接口,它并不会滤除某些能力,也不会简化接口。如果客户系统期待的API不可用,那就需要用到适配器。
适配器可被实现为不兼容的方法调用之间的一个代码薄层。如果你有一个具有3个字符串参数的函数,但客户每户拥有的却是一个包含三个字符串元素的数组,此时就可以用一个适配器来衔接二者。
如:假设你有一个对象,还有一个以三个字符串为参数的函数:
var clientObject ={
string1:’foo’,
string2:’bar’,
string3:’baz’
};
function interfaceMethod(str1,str2,str3){
…
}
为了把clinetObject作为参数传递给interfaceMethod,需要适配器,我们可以这样创建一个:
functon clientToInterfaceAdapter(o){
interfaceMethod(o.string1, o.string2, o.string3)
}
clientToInterfaceAdapter函数的作用就在于对interfaceMethod函数进行包装,并把传递给它的参数转换为后者需要的形式。
适配原有实现
在某此情况下,从客户一方对代码进行修改是不可能的。有些程序员因此索性名句创建API。如果现有的接口发生了改变,那么客户代码也必须进行相应的修改后才能用这个新的接口,否则整个应用系统就有失灵的危险。在引入新接口之后,一般说来最好向客户方提供一些可为其实现新接口的适配器。
以PC硬件为例,PS2插口是连接鼠标和键盘的标准接口。多年以来几乎所有PC都带有这种接口。后来出现USB。那之前生产的ps2鼠标没买完怎么办!整了个ps2-to-usb适配器就产生啦。