适配器是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口。比如:电源适配器、三角架基座转接部件、USB与串口的转接设备等。

比如我买的超极本没有传统网口,只有一个typeC接口,就必须从网上买一个转换器,它能将两个接口完全不同的物体连接起来。

Spring jetty选择器和接收器配置_System

而平常我们开发的时候可能也会遇到这种情况,老旧接口需要进行改造,以适应新的接口规则,但是这样违背了我们的开闭原则,

适配器模式提供给我们全新的思路去完成这样的改造,给他们提供一个中间件,不需要去修改两边的接口,将变化的部分控制在适配器中。

适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

适配器模式分为两类:对象适配器和类适配器

Spring jetty选择器和接收器配置_设计模式_02

Spring jetty选择器和接收器配置_适配器_03

由于类适配器是使用多重继承来实现的,所以在java中不适用,本文只介绍对象适配器。

上图中的Client认为自己只是在调用Target中的request方法,而Adapter实现了Target接口中的requst方法,在Adapter中request方法被调用时,会委托给Adaptee,Client以新接口的request方法调用形式最终调用了Adaptee里的specificRequest方法。

下面贴代码

首先定义一个包含鸭子行为的接口

//鸭子行为接口
public interface Duck {
	public void quack();
	public void fly();
}

再实现一个具体的鸭子子类

//具体鸭子子类
public class MallarDuck implements Duck{
	
	@Override
	public void quack() {
		System.out.println("我是一只鸭子,我正在叫");
	}

	@Override
	public void fly() {
		System.out.println("我是一只鸭子,我正在飞");
	}

}

定义包含火鸡行为的接口,可以看到火鸡和鸭子的叫的方法不一样

//火鸡行为接口
public interface Turkey {
	public void gobble();
	public void fly();
}

接着定义火鸡的具体子类

//具体的火鸡子类
public class WildTurkey implements Turkey{

	@Override
	public void gobble() {
		System.out.println("我是火鸡,我正在叫");
	}

	@Override
	public void fly() {
		System.out.println("我是火鸡,我飞了稍短的一些距离");
	}

}

定义对象适配器,该适配器类构造函数传入了火鸡对象,实现了鸭子接口中的两个方法,而在鸭子所具有的两个方法中,调用了火鸡的两个方法,将请求委托给了火鸡子类进行处理。

//对象适配器
public class TurkeyAdapter implements Duck{
    Turkey turkey;
	
	public TurkeyAdapter(Turkey turkey){
		this.turkey = turkey;
	}
	
	@Override
	public void quack() {
		turkey.gobble();
	}

	@Override
	public void fly() {
		turkey.fly();
	}

}

最后一步,测试类进行测试

//适配器模式测试代码
public class AdapterTest {

	public static void main(String[] args) {
		MallarDuck mallarDuck = new MallarDuck();

		WildTurkey turkey = new WildTurkey();
		Duck turkeyAdapter = new TurkeyAdapter(turkey);
		
		System.out.println("The Turkey says...");
		turkey.gobble();
		turkey.fly();
		
		System.out.println("The Duck says...");
		testDuck(mallarDuck);
		System.out.println("The TurkeyAdapter says...");
		testDuck(turkeyAdapter);
	}
	
	static void testDuck(Duck duck){
		duck.quack();
		duck.fly();
	}
}

可以看到TurkeyAdapter和MallarDuck都可以调用testDuck,使用Duck接口的方法,但是TurkeyAdapter却不是一个真正的鸭子类,它只是一个披着鸭子皮的火鸡。

Spring jetty选择器和接收器配置_适配器_04

 

在SpringMVC中就用到适配器模式,大家有兴趣可以去看看。