定义:
- 适配器模式属于结构型模式,又称包装器模式。它可以将某个类的接口转换成客户端期望的另一个接口表示,使得原本因接口不匹配不能一起工作的两个类可以协同工作,保证了兼容性。
工作原理:用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法,用户收到反馈结果,感觉只是和目标接口交互。
适配器的实现方式有三类:类适配器模式、对象适配器模式和接口适配器模式。
1. 类适配器模式
基本介绍:Adapter
类通过继承 src
类并实现 dst
类接口,从而完成 src->dst
的适配。
以生活中充电器的例子来讲解适配器,充电器本身相当于 Adapter
,220V 交流电相当于 src
,5V 直流电相当于 dst
.
分析的 UML 类图如下所示:
Voltage5V
类
public interface Voltage5V { int output5V(); }
Voltage220V
类
public class Voltage220V { public int output220V() { int src = 220; System.out.println("电压"+src+"伏"); return src; } }
VoltageAdapter
类
public class VoltageAdapter extends Voltage220V implements Voltage5V { @Override public int output5V() { int src = output220V(); int dst = src / 44; //转换成5V return dst; } }
Phone
类
public class Phone { public void charging(Voltage5V voltage5V) { if (voltage5V.output5V() == 5) { System.out.println("电压为5V,可以充电"); } else if (voltage5V.output5V() > 5) { System.out.println("电压大于5V,不能充电"); } } }
Client
类
public class Client { public static void main(String[] args) { System.out.println("类适配器模式"); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }
类适配器的注意事项:
由于 Java 是单继承机制,因此当适配器需要继承 src 类时,这就要求 dst 必须是接口,有一定的局限性。
src 类的方法在 Adapter 中都会暴露出来,增加了使用成本。
由于其继承了 src 类,因此可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。
2. 对象适配器模式
基本介绍:其基本思路与类适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类而是持有 src 类的实例以解决兼容性的问题,即:持有 src 类实现 dst 类接口完成 src->dst 的适配。
分析充电器适配的例子,其 UML 类图如下:
VoltageAdapter
类
public class VoltageAdapter implements Voltage5V{ private Voltage220V voltage220V; //关联关系-聚合 public VoltageAdapter(Voltage220V voltage220V) { this.voltage220V = voltage220V; } @Override public int output5V() { int dst = 0; if (voltage220V != null) { int src = voltage220V.output220V(); System.out.println("使用对象适配器,进行适配"); dst = src / 44; System.out.println("适配完成,输出的电压为"+dst); } return dst; } }
Client
类
public class Client { public static void main(String[] args) { System.out.println("对象适配器模式"); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); } }
对象适配器的优点:
- 使用组合替代继承,克服了类适配器必须继承
src
的局限性,也不要求dst
必须是接口。
3. 接口适配器模式
基本介绍:
当不需要实现接口的全部方法时,可以先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择覆盖父类的某些方法来实现需求。
适用于一个接口不想使用其所有的方法的情况。
4. 适配器模式在 SpringMVC 中的应用
SpringMVC 中的处理器适配器 HandlerAdapter
就使用了适配器模式:
HandlerAdpater
作为一个适配器接口,它的实现子类使得每一种 Controller 有对应的适配器实现类- 适配器代替 Controller 执行相应的方法
- 扩展 Controller 时,只需要增加一个适配器类就完成了
SpringMVC
的扩展了
5. 小结
三种命名方式是根据 src
以怎样的形式给到 Adapter
来命名:
- 类适配器:以类给到,在 Adapter 类里,将
src
当作类继承 - 对象适配器:以对象给到,在 Adapter 类里,将
src
作为一个对象持有 - 接口适配器:以接口给到,在 Adapter 类里,将
src
作为一个对象实现
适配器模式就是将原本不兼容的接口融合到一起工作。