# 适配器模式 ( Adapter ) ## 别名 > Wrapper (包装器) ## 用途 > 将一个类的接口转换成客户希望的另外一个接口。 Adapter模式使得原本由于接口不兼容 而不能一起工作的那些类可以一起工作。 ## 实例 > 假设一下你的存储卡里有一些照片,你需要把它们转移到你的电脑上。为了转移它们,你 需要一些与你的电脑接口兼容的适配器,这样你就可以将存储卡连接到你的电脑上。这里, 读卡器就起到了适配器的作用。更经典的例子就是人尽皆知的电源适配器了,一个三脚的 插头不能连接到两个孔的插座上,它需要一个电源适配器,使它与两个分叉的插座兼容。 ## 模式分析 > 假定现在有一个小汽车司机,他只会驾驶小型汽车,并不会驾驶公共汽车。 > > 现在分别定义小汽车 ( Car ) 和公共汽车 ( Bus ) 两种接口 ``` public interface Car { void drive(); } public class Bus { private static final Logger LOGGER = LoggerFactory.getLogger(Bus.class); public void run() { LOGGER.info("公共汽车在行驶"); } } ``` > 这个司机需要获得一辆小汽车才能进行驾驶活动 ``` public class Driver implements Car { private Car car; @Override public void drive() { car.drive(); } public Driver(Car car) { this.car = car; } } ``` > 现在这个司机有急事,必须马上赶往公司,可是只借到了一辆公共汽车,并且车上没有任何人, 现在必须马上将司机的驾驶小汽车的技能转化成驾驶公共汽车的技能 ``` public class BusAdapter implements Car { private Bus bus; public BusAdapter() { this.bus = new Bus(); } @Override public void drive() { bus.run(); } } ``` > 经过技能转化,司机成功的驾驶公共汽车驶向了公司 ## 适用场景 >* 需要使用的类的接口与需要的接口类型不匹配 >* 需要创建一个可重用的类,它可以与不相关的或不可预见的类进行协作,也就是说, 类不一定具有兼容的接口 >* 需要使用几个现有的子类,但是通过子类化每个子类来调整它们的接口是不切实际的。 对象适配器可以调整其父类的接口。 ## 类适配器和对象适配器的区别 >* 类适配器的适配功能是通过被适配类(接口)的一个对象间接完成的。因此,类适配器不能无法 对被适配类的所有子类进行适配 >* 类适配器重写了被适配类(接口)的方法,所以,类适配器可以看做被适配类(接口)的一个子类 >* 类适配器一般只需持有一个被适配类(接口)的对象,并不需要额外的对被适配类(接口)的引用 >* 对象适配器可以和多个被适配类(接口)的对象协同工作——即被适配类(接口)本身及其所有子类。适配器也可以一次为所有的被适配类(接口)添加自定义的功能。 >* 对象适配器使得重写被适配类(接口)的方法变成了不可能,这时需要的是被适配类(接口)的子类,而不是被适配类(接口)本身