设计模式08-适配器模式

适配器模式(Adapter Pattern)是指将一个类的接口转换成用户期望的另一个接口,使原本接口不兼容的类可以一起工作。适配器模式属于结构型设计模式。

示例代码

示例类图:

https://github.com/chenpenghui93/design-pattern/tree/master/src/main/java/com/example/designpattern/adapter

JDK实例

1
2
3
4
5
//数组和list对象转换
java.util.Arrays#asList()
//字符流和字节流的转换
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)

Spring实例

1、SpringAOP中的AdvisorAdapter类有三个实现类 MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter和ThrowsAdviceAdapter,先来看顶层接口 AdvisorAdapter 的源代码

1
2
3
4
5
6
7
8
9
10
package org.springframework.aop.framework.adapter;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;

public interface AdvisorAdapter {
boolean supportsAdvice(Advice var1);
MethodInterceptor getInterceptor(Advisor var1);
}

MethodBeforeAdviceAdapter实现类源码(其它两个类可自行查看):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.springframework.aop.framework.adapter;

import java.io.Serializable;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.MethodBeforeAdvice;

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
MethodBeforeAdviceAdapter() {
}
public boolean supportsAdvice(Advice advice) {
return advice instanceof MethodBeforeAdvice;
}
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}

Spring会根据不同的AOP配置来确定使用对应的Advice。

2、SpringMVC中的HandlerAdapter类有多个子类,如下类图,在DispatcherServlet的doDispatch()方法中会进行适配调用; 在 doDispatch()方法中调用了 getHandlerAdapter()方法;在 getHandlerAdapter()方法中循环调用了 supports()方法判断是否兼容,循环迭代集 合中的 Adapter 又是在初始化时早已赋值

适用场景

  • 已经存在的类,它的方法和需求不匹配(方法结果相同或类似)的情况
  • 适配器模式不是软件设计阶段考虑的设计模式,而是随着软件维护、更新,用于解决”不同产品、厂家等提供的功能类似而接口不同”的问题

模式优点

  • 能提高类的透明性和复用性,可直接复用现有的类,而不需要修改现有类
  • 目标类与适配器类解耦,提高程序的可扩展性
  • 在很多业务场景中符合开闭原则

模式缺点

  • 适配器编写过程中需要全面考虑,可能会增加系统复杂度
  • 降低代码可读性,增加了阅读难度,过多使用适配器会使系统代码变得凌乱

参考