适配器模式:
将一个类的的接口转换成客户端期望的另一个接口表示,主要的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,别名为包装器(Wrapper)
适配器属于结构型设计模式,主要分为三类:类适配器,对象适配器,接口适配器
三种角色:
Target(目标接口):客户端所需要的接口,可以是接口或者抽象类,也可以是实体类
Adaptee(需要适配的类):被适配者,也就是想要加入的,想成为目标接口可用的类
Adapter(适配器):把原接口转换成目标接口的类
类适配器
目标接口需要的是USB接口类型的类
public class Computer { public String useUsb(USB usb){ return usb.provideUsbDoSomething(); } }
需要适配的类,此刻Computer无法通过USB方法接入苹果手机
public interface AppleCharge { String provideAppleCharge(); }
public class ApplePhone implements AppleCharge{ @Override public String provideAppleCharge() { return "苹果手机接入充电接口"; } }
适配器类:
public class USBAdapter extends ApplePhone implements USB { @Override public String provideUsbDoSomething() { return provideAppleCharge(); } }
这样Computer类可以传入一个适配器去接入苹果手机,而Computer使用USB方法完全无需改动
public class Computer { public String useUsb(USB usb){ return usb.provideUsbDoSomething(); } public static void main(String[] args) { Computer computer = new Computer(); computer.useUsb(new USBAdapter()); } }
缺点:适配器使用了继承的方式去获得使用苹果手机充电方法,适配器只能继承一个类,后期扩展比较差,所以实际开发用的比较少
对象适配器
public class USBAdapter implements USB { private ApplePhone applePhone; public USBAdapter(ApplePhone applePhone) { this.applePhone = applePhone; } @Override public String provideUsbDoSomething() { return applePhone.provideAppleCharge(); } }
我们把继承改为使用组合的方式,根据'合成复用原则',在系统中尽量使用关联关系(组合)来替代继承关系,这样保留了适配器的单根继承,也解决了适配问题,增强了扩展性
接口适配器(缺省适配器)模式:
一个接口可能有很多抽象方法,我们只想要使用其中一个或部分,但是我们如果直接使用该接口需要实现全部方法,这样代码看起臃肿.
为了解决这个问题,我们使用一个抽象类去实现这个接口,但是使用缺省实现,我们需要使用接口中某一方法,直接使用抽象类重写接口某一方法即可
public class InterfaceAdapter { public static void main(String[] args) { test(new AdapterClass() { @Override public void testMethod3() { super.testMethod3(); } }); } public static void test(TestInterface ti){ ti.testMethod3(); } } //Target接口 interface TestInterface{ void testMethod1(); void testMethod2(); void testMethod3(); void testMethod4(); void testMethod5(); } //适配器角色 abstract class AdapterClass implements TestInterface{ /* (non-Javadoc) * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod1() */ @Override public void testMethod1() { } @Override public void testMethod2() { } /* (non-Javadoc) * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod3() */ @Override public void testMethod3() { } /* (non-Javadoc) * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod4() */ @Override public void testMethod4() { } /* (non-Javadoc) * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod5() */ @Override public void testMethod5() { } }
适配器模式在很多源码都有涉及,比如
- * JDK中的LocaleProviderAdapter(在Calendar中有使用)
- * InputStreamReader和OutputStreamWriter (字节字符流适配器)
- * SpringMVC中的HandlerAdapter