适配器模式

581 阅读5分钟

适配器模式

一、适配器模式定义

适配器模式的定义是,Convert the interface of a class into another interface clients expect,将某个类的接口转换为接口客户所需的类型。 适配器模式解决的问题是,使得原本由于接口不兼容而不能一起工作、不能统一管理的那些类可以在一起工作、可以进行统一管理。

将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)

适配器的使用场景:

  1. 接口转换
  2. 想要创建一个可以重复使用的类,同时这些重复的类彼此之间没有相同关系。

二、类适配器

1.类适配器的定义

类的是适配器模式把适配的类的API转换为目标类的API 采用继承方式的称为类适配器 特点:通过多重继承不兼容接口,实现对目标接口的匹配,单一的为某个类而实现适配。

2.UML结构图

类适配器UML.png

3.代码示例

之所以称为类适配器是因为他是通过Adapter类来继承适配者类Adaptee完成的。

Target:

public interface Target {
	
	void sampleOperation1();
	void sampleOperation2();

}

Adaptee:

public class Adaptee {

	public void sampleOperation1(){
		System.out.println("sampleOperation1");
	}
}

Adapter:

public class Adapter extends Adaptee implements Target{

	@Override
	public void sampleOperation2() {
		System.out.println("sampleOperation2");
	}

}

MyClass:

public class MyClass {
	
	public static void main(String[] args) {
		Adapter adapter = new Adapter();
		adapter.sampleOperation1();//sampleOperation1
		adapter.sampleOperation2();//sampleOperation1
	}
}

4.总结

  • 类适配器使用对象继承的方式,是静态的定义方式
  • 对于类适配器,适配器可以重定义Adaptee的部分行为。
  • 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到适配者Adaptee
  • 对于类适配器,由于适配器直接继承了Adaptee,使得适配器Adapter不能和Adaptee的子类一起工作

三、对象适配器

1.对象适配器定义

与类适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。 采用组合方式的适配器称为对象适配器 特点:把“被适配者”作为一个对象组合到适配器类中,接口包装被适配者。

2.UML结构图

对象适配器UML.png

3.代码示例

通过持有Adaptee的引用来完成了sampleOperation1()方法,而不是自己再定义。之所以称为对象适配器,是因为持有了对象的引用。

Target:

public interface Target {
	void sampleOperation1();
	void sampleOperation2();
}

Adaptee:

public class Adaptee {
	
	public void sampleOperation1(){
		System.out.println("sampleOperation1");
	}

}

Adapter:

package com.hcx.object;

public class Adapter implements Target{
	
	private Adaptee adaptee;
	
	public Adapter(Adaptee adaptee) {
		this.adaptee = adaptee;
	}

	@Override
	public void sampleOperation1() {
		//直接使用adaptee中的sampleOperation1方法
		adaptee.sampleOperation1();
	}

	@Override
	public void sampleOperation2() {
		//自己编写
		System.out.println("sampleOperation2");
	}
	
}

4.总结

Adapter只实现了target接口,没有继承Adaptee适配者类。Adapter类持有了Adaptee的引用,实现sampleOperation1()的时候,使用adaptee的引用来直接调用Adaptee适配者类里面的sampleOperation1(),而不是自己再去实现。就通过了一个委托的形式把adapter类和adaptee类进行了关联。

  • 对象适配器使用对象组合的方式,是动态的组合方式。
  • 对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。(可以把多个不同的adaptee类通过一个Adapter适配器类转换成同一个target目标)
  • 对于对象适配器,要重定义Adaptee的行为比较困难。
  • 对于对象适配器,需要额外的引用来间接得到Adaptee。

四、只定义一个适配器实现类

这种方式类似于多功能充电器,一个电源插头上接着多种类型的充电接口。用户在使用时需要使用电器接口与多功能充电器上的充电接口逐个进行对比,接口匹配,则可以充电。

五、为每一个对象都定义一个适配器

见demo

六、缺省适配器

缺省适配器模式是由适配器模式简化而来,省略了适配器模式中目标接口,也就是源接口和目标接口相同,源接口为接口,目标接口为类。 典型的缺省适配器模式是 JavaEE 规范中的 Servlet 接口与GenericServlet 抽象类。 Servlet 接口中包含五个抽象方法,而其中的 service()方法才是用于实现业务逻辑的、必须要实现的方法,另外四个方法一般都是空实现,或简单实现。 GenericServlet 抽象类实现了 Servlet 接口的 service()方法以外的另外四个方法,所以自定义的 Servlet 只需要继承 GenericServlet 抽象类,实现 service()方法即可。无需再实现Servlet 接口了。

作用: 1.透明:通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。 2.重用:复用了现存的类,解决了现存类和复用环境要求不一致的问题。 3.低耦合:将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码(遵循开闭原则)

Demo链接:github.com/GitHongcx/d…