设计模式系列8-适配器模式
适配器模式(Adapter Pattern)是指将一个类的接口转换成客户期望的另一个接口,使 原本的接口不兼容的类可以一起工作,属于结构型设计模式
应用场景
- 已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
- 适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案。有点亡羊补牢的感觉。
生活中也非常的应用场景,例如电源插转换头、手机充电转换头、显示器转接头。
案例
在中国民用电都是 220V 交流电,但我们手机使用的锂电池使用的 5V 直流电。因此,我们给手机充电时就需要使用电源适配器来进行转换
220V交流电
创建 AC220 类,表示 220V 交流电
public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出电流" + output + "V");
return output;
}
}
5V电流
创建 DC5 接口,表示 5V 直流电的标准
public interface DC5 {
int outoupDC5V();
}
适配器
创建电源适配器 PowerAdapter 类
public class PowerAdapter implements DC5 {
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
public int outoupDC5V() {
int adapterInput = ac220.outputAC220V();
int adapterOutput = adapterInput / 44;
System.out.println("使用PowerAdapter输入AC:" + adapterInput + "V,输出DC:" + adapterOutput + "V");
return adapterOutput;
}
}
测试
public static void main(String[] args) {
DC5 dc5 = new PowerAdapter(new AC220());
dc5.outoupDC5V();
}
通过增加 PowerAdapter 电源适配器,实现了二者的兼容
源码体现
Spring
Spring 中适配器模式也应用得非常广泛,例如:SpringAOP 中的 AdvisorAdapter 类, 它有三个实现类 MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter 和ThrowsAdviceAdapter,先来看顶层接口 AdvisorAdapter 的源代码
public interface AdvisorAdapter {
boolean supportsAdvice(Advice var1);
MethodInterceptor getInterceptor(Advisor var1);
}
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
Spring 会根据不同的 AOP 配置来确定使用对应的 Advice,跟策略模式不同的一个方法可以同时拥有多个 Advice
SpringMVC
下面再来看一个 SpringMVC 中的 HandlerAdapter 类,它也有多个子类

其适配调用的关键代码还是在 DispatcherServlet 的 doDispatch()方法中
# 在 doDispatch()方法中调用了 getHandlerAdapter()方法
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
# 在 getHandlerAdapter()方法中循环调用了 supports()方法判断是否兼容,循环迭代集 合中的 Adapter 又是在初始化时早已赋值
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
适配器模式的优缺点
- 优点:
- 能提高类的透明性和复用,现有的类复用但不需要改变。
- 目标类和适配器类解耦,提高程序的扩展性。
- 在很多业务场景中符合开闭原则。
- 缺点:
- 适配器编写过程需要全面考虑,可能会增加系统的复杂性。
- 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

浙公网安备 33010602011771号