适配器模式之类的适配器模式与对象的适配器模式

适配器模式有类的适配器模式和对象的适配器模式两种不同的形式,如下图所示,左边是类的适配器模式,右边是对象的适配器模式。

适配器模式之类的适配器模式与对象的适配器模式_第1张图片

的适配器模式:

以下是uml类图:

适配器模式之类的适配器模式与对象的适配器模式_第2张图片

模式所涉及的角色有:

*目标(Target)角色:这就是所期待得到的接口。注意,由于这里讨论的是类适配器模式,因此目标不可以是类。

*源(Adaptee)角色:现有需要适配的接口。

*适配器(Adapter)角色:适配器类是本模式的核心,适配器把源接口转换成目标接口,显然,这一角色不可以是接口,而必须是具体类。

该模式的实现源码为:

Target:

package Adapter.ClassAdapter;

public interface Target {

	/*
	 * 这是源类也有的方法sampleOperation1
	 */
	void sampleOperation1();
	
	/*
	 * 这是源类没有的方法sampleOperation2
	 */
	void sampleOperation2();

}
上面给出的是目标角色的源代码,这个角色是以一个java接口的形式实现的,可以看出,这个接口声明了两个方法:sampleOperation1()和

sampleOperation2()。而源角色Adaptee是一个具体类,它有一个sampleOperation1()方法,但是没有sampleOperation2()方法,如下所示:

Adaptee:

package Adapter.ClassAdapter;

public class Adaptee {
	
	/*
	 * 源类含有方法sampleOperation1
	 */
	public void sampleOperation1(){}

}
适配器角色Adapter扩展了Adaptee,同时又实现了目标接口,由于Adaptee没有提供sampleOperation2()方法,而目标接口又要求这个方法,

因此适配器角色Adapter实现了这个方法,如下所示:

package Adapter.ClassAdapter;

public class Adapter extends Adaptee implements Target{

	/*
	 * 由于源类没有方法sampleOperation2
	 * 因此适配器类补充上这个方法
	 * @see ClassAdapter.Target#sampleOperation2()
	 */
	public void sampleOperation2() {
		
	}


}
总结:

使用一个具体类把源(Adaptee)适配到目标(Target)中,这样一来,如果源以及源的子类都是用此类适配,就行不通了。

由于适配器类是源的子类,因此可以在适配器类中置换掉源的一些方法。

对象的适配器模式:

适配器模式之类的适配器模式与对象的适配器模式_第3张图片

该模式所涉及到的角色为:

*目标(Target)角色:这是所期待的的接口,目标可以是具体的或抽象的类。

*源(Adaptee)角色:现有需要适配的接口。

*适配器(Adapter)角色:适配器是本模式的核心,适配器把源接口转换成目标接口,显然,这一角色必须是具体类。

源码如下:

Target:

package Adapter;

public interface Target {
	
	/*
	 * 这是源类也有的方法 sampleOpertion1
	 */
	void sampleOperation1();
	
	/*
	 * 这是源类没有的方法sampleOperation2
	 */
	void sampleOperation2();
}
Adaptee:

package Adapter;

public class Adaptee {
	
	/*
	 * 源类有方法sampleOperation1
	 */
	public void sampleOperation1(){}
}
Adapter:

package Adapter;

public class Adapter implements Target {

	private Adaptee adaptee;

	public Adapter(Adaptee adaptee){
		this.adaptee=adaptee;
	}
	
	/*
	 * 源类有方法sampleOperation1因此适配器类直接委派即可
	 * @see Adapter.Target#sampleOperation1()
	 */
	public void sampleOperation1() {
		adaptee.sampleOperation1();
	}

	/*
	 * 源类没有方法sampleOperation2
	 * 因此由适配器类需要补充此方法
	 * @see Adapter.Target#sampleOperation2()
	 */
	public void sampleOperation2() {
		
	}

}
对象适配器模式的效果为:

*一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。

*与类的适配器模式相比,要想置换源类的方法本来就不容易,如果一定要置换源类的一个或者多个方法,就只能先做一个源类的子类,

将源类的方法置换掉,然后再把源类的子类当做真正的源进行适配。

在什么情况下使用适配器模式:

(1)系统需要使用现有的类,而此类的接口不符合系统的需要。

(2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,

这些源类不一定有很复杂的接口。

(3)(对对象的适配器模式而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类

做一个适配器类,而这不太实际。

你可能感兴趣的:(设计模式,适配器模式)