设计模式记录(3.1)
第四部分 结构模式
第二十二章 适配器模式
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法再一起工作的两个类能够在一起工作。
它同时也叫做变压器模式和包装模式。
适配器的两种形式
适配器模式有类的适配器模式和对象的是撇弃模式。如下图,左边的是类适配器模式,右边的是对象适配器模式。
类的适配器模式的结构
类的适配器模式把被适配的类的API转换成目标类的API,结构图如下:
在上图中可以看出,Adaptee类并没有sampleOperation2()方法,而客户端要这个方法,为使客户端能够使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter和Adaptee是继承关系,这就决定了适配器的模式是类的。
代码如下:
Target的源代码:
package com.javapatterns.adapter.classAdapter;public interface Target { void sampleOperation1(); void sampleOperation2();}Adaptee的源代码:
package com.javapatterns.adapter.classAdapter;public class Adaptee { public void sampleOperation1(){}}Adapter源代码:
package com.javapatterns.adapter.classAdapter;public class Adapter extends Adaptee implements Target { public void sampleOperation2(){ // Write your code here }}个人理解:就是Adaptee这个源角色的方法不够用了,此时就用接口Target来补充,最后使用子类Adapter来实现。
类的适配器模式的结构:
使用一个具体类把源(Adaptee)适配到目标(Target)中,这样一来,如果源以及源的子类都使用此类适配,就行不通了。
由于适配器时源的子类,因此可以在适配器类中置换掉源的一些方法。
由于只引进了一个适配器类,因此只有一个路线到达目标类,使问题得到简化。
对象的适配器模式的结构
结构图如下:

直接上代码:
Target源代码:
package com.javapatterns.adapter.objectAdapter;public interface Target { void sampleOperation1(); void sampleOperation2();}Adaptee(需要扩展功能的类)源代码:
package com.javapatterns.adapter.objectAdapter;public class Adaptee { public void sampleOperation1(){}}Adapter(扩展后的类)源代码:
package com.javapatterns.adapter.objectAdapter;public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee){ super(); this.adaptee = adaptee; } public void sampleOperation1(){ adaptee.sampleOperation1(); } public void sampleOperation2(){ // Write your code here } }总结:
读者不要误以为适配器模式就是为了补充源角色没有的方法而准备的!
对象适配器模式的效果:
1.一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以以源类和它的子类都适配到目标接口。
2.与类的适配器模式相比,要想置换源类的方法就不容易。如果一定要置换掉源类的一个或多个方法,就只要先做一个源类的子类,将源类的方法置换掉,然后再把源类的子类当做真正的源进行适配。
3.虽然要想置换源类的方法不容易,但是要想增加一些新的方法则方便得很,而且增加的方法可同时适用于所有的源。
在什么情况下使用适配器模式
1.系统需要使用现有的类,而此类的接口不符合系统的要求。
2.想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。
3.(对对象的适配器模式而言)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器类,而这不符合实际。
第二十三章 缺省适配模式
直接给出一个鲁智深的例子图:

其中天英星这个抽象类便是一个适配器类。它把鲁智深不需要实现的方法,采用了空的实现,所以鲁智深就不用再去实现这些方法了。