一、面向对象适配器
假设已有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新厂商所设计出来的接口,不同于旧厂商的接口。图01.jpg
你不想改变现有的代码,解决这个问题(而且你也不能改变厂商的代码)。所以该怎么做?这个嘛,你可以写一个类,将新厂商接口转换成你所期望的接口。图02.jpg
这个适配器工作起来就如同一个中间人,它将客户所发出的请求转换成厂商类能理解的请求。图03.jpg
二、例子
如果它走起路来像只鸭子,叫起来像只鸭子,那么它可能是一只包装了鸭子适配器的火鸡。
鸭子接口:图04.jpg
绿头鸭子是鸭子的子类:图05.jpg
为您介绍最新的“街头顽禽”:图06.jpg,图07.jpg
现在,假设你缺鸭子对象,想用一些火鸡对象来冒充,显而易见,因为火鸡的接口不同,所以我们不能公然拿来用。那么,就写个适配器吧:图08.jpg
三、适配器模式解析
现在我们已经知道什么是适配器了,让我们再次看看各部分之间的关系。图09.jpg
客户使用适配器的过程如下:
1、客户通过目标接口调用适配器的方法对适配器发出请求。
2、适配器使用被适配者接口把请求转换成被适配者的一个或者多个调用接口。
3、客户接受到调用的结果,但并未察觉这一切是适配器在起转换作用。
请注意:客户和被适配者是解耦的,一个不知道另一个。
四、定义适配器模式
适配器模式 将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
现在,我们知道,这个模式可以通过创建适配器进行接口转换,让不兼容的接口变成兼容。这可以让客户从实现的接口解耦。如果在一段时间之后,我们想要改变接口,适配器可以将改变的部分封装起来,客户就不必为了应对不同的接口而每次跟着修改。
类图:图10.jpg
这个适配器模式充满着良好的OO设计原则:使用对象组合,以修改的接口包装被适配者:这种做法还有额外的优点。那就是,被适配者的任何子类,都可以搭配着适配器使用。
也请留意,这个模式是如何把客户和接口绑定起来,而不是和实现绑定起来的。我们可以使用数个适配器,每一个都负责转换不同组的后台类。或者,也可以加上新的实现,只要他们遵守目标接口就可以。
五、适配器的分类
现在,尽管已经定义了这个模式,但其实我们还没有告诉你有关的一切。实际上有”两种“适配器:”对象“适配器和”类“适配器。上面的类图是对象适配器的图。
究竟什么是”类“适配器?为什么我们还没告诉你这种适配器?因为你需要多重继承才能实现它,这在Java中是不可能。但是当你在使用多重继承语言的时候,还是可能遇到这样的需求。让我们看看多重继承的类图。图11.jpg
看起来很熟悉吗?没错,唯一的差别就在于适配器继承了Target和Adaptee。而对象适配器利用组合的方式将请求传送给被适配者。
六、回顾要点
1、当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
2、适配器改变接口以符合客户的期望。
3、实现一个适配器可能需要一番功夫,也可能不费功夫,视目标接口的大小与复杂度而定。
4、适配器模式有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。
5、适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任。