什么是适配器模式?
适配器模式:是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。这种模式通常用于解决接口不兼容的情况,使得原本由于接口不匹配而无法在一起工作的类可以一起工作,总而言之,就是将两个不兼容的接口通过一定的方式使之兼容
在生活中,适配器模式也非常常见,如 语言翻译器、USB转接头、电源适配器等
这些常见的实例都体现了适配器模式的核心思想:解决不同接口之间的兼容性问题,使原本不兼容的组件可以一起工作
适配器模式角色:
Target: 目标接口(可以是抽象类或接口),是客户端代码期望的接口。适配器会实现这个接口,以便客户端可以通过它来调用适配器的功能。
Adapter:****适配器类,是适配器模式的核心,通过继承或引用适配者的对象,将适配者转换为目标接口
Adaptee: 适配者,与Target不兼容
client:需要使用适配器的对象
适配器模式的实现
在之前的文章:**SpringBoot日志 **中使用的 SLF4J 就使用了适配器模式,SLF4J 提供了一系列打印日志的API,底层调用的是 log4j 或是 logback 来进行日志打印,而我们作为调用者,只需要调用 SLF4J 的API即可
因此,我们就以 slf4j 和 log4j 为例,进一步理解适配器模式
我们定义一个 slf4j 接口:
public interface Slf4jLog {
void log(String message);
}
log4j 接口:
public class Log4j {
public void log4jPrint(String message){
System.out.println("Log4j:" + message);
}
}
slf4j 和 log4j 适配器:
public class Slf4jLog4jAdapter implements Slf4jLog{
private Log4j log4j;
public Slf4jLog4jAdapter(Log4j log4j){
this.log4j = log4j;
}
@Override
public void log(String message) {
log4j.log4jPrint("适配器:" + message);
}
}
最后,客户端调用 slf4j:
public class Main {
public static void main(String[] args) {
Slf4jLog slf4jLog = new Slf4jLog4jAdapter(new Log4j());
slf4jLog.log("客户端调用");
}
}
运行结果:
通过运行结果,我们可以看出,在适配器的转换下,成功调用了 log4j
我们不需要改变log4j的API,只需要通过适配器的转换,就可以更换日志框架,保证系统的平稳运行
在Spring MVC中的应用
在Spring MVC中,**DispatcherServlet **会根据用户请求选择合适的 HandlerAdapter,并将请求交给适配器处理。适配器会根据请求的处理器类型(Handler)选择合适这个Handler的适配器子类,并将请求适配到处理方法上,最终返回处理结果。
DispatcherServlet中的doDispatch:
** doDispatch 先找到与请求对应的handler,再调用 getHandlerAdapter,找到可以处理该handler的HandlerAdapter**
getHandlerAdapter:
在getHandlerAdapter中,通过supports方法寻找合适handler的适配器,并返回
获取的适配器(ha) 通过 handle 方法,调用处理器进行处理,返回MolelAndVie(mv)
应用场景
一般来说,适配器模式可以看做是一种“补偿模式”,用于补救设计上的缺陷,若在设计初期就能够协调规避接口不兼容问题,就不需要使用适配器模式了。
因此适配器模式更多的应用场景是对正在运行的代码进行改造,并希望可以复用原有代码实现新的功能,如 集成第三方组件、旧系统升级 等
版权归原作者 楠枬 所有, 如有侵权,请联系我们删除。