适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
比如国外标准电压110v,而我们国家是220v的,国外很多电器没有办法在国内使用,那么这时候使用电源适配器,甭管多少v电压,全部转成我需要的。
系统的数据和行为都正确,但接口不符时,我们应该考虑使用适配器,目的是是控制范围之外的一个原有对象与某个接口匹配。
适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的清空,比如在需要对早期代码服用的一些功能等应用上又很实际的价值。
类适配器模式
类适配器使用多重集成对一个接口与另外一个接口进行匹配
image.png
在类适配器模式中,adapter将有机会重新定义adaptee的接口实现,适用于target和adaptee都被其他调用方以接口方式调用的地方。
对象适配器模式
对象适配器依赖于对象组合。
image.png
在对象适配器中,一个adapter可以适配多个adaptee,多用于使用一个已经存在的实体类。
使用
- 想使用一个已经存在的类,而他的接口不符合你的需求。
- 想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
- 使用一个已经存在的子类(对象适配器模式),单是不可能对每一个都进行子类化以匹配他们的接口。
SpringMVC中的适配器模式
在SpringMVC中,使用DispatcherSevlet拦截所有请求,再根据不同的uri调用对应的服务方法。DispatcherSevlet中最核心的doDispatch()方法,截取一段分发服务的代码,这里就用到了适配器模式
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
...
}
1、首先我们来看这个适配器接口(HandlerAdapter )
public interface HandlerAdapter {
boolean supports(Object var1);
@Nullable
ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
long getLastModified(HttpServletRequest var1, Object var2);
}
HandlerAdapter接口约束了他的子类必须实现的三个方法,判断是否支持这个handler,执行handler并返回ModelAndView对象,获取最近一次修改时间。
很明显这个HandlerAdapter就是为了针对不同的服务实现返回同样的视图。
这里,需要了解一下SpringMVC中有多少种服务的实现方式,看一下下面的实现类:
image.png最典型的三个:
- 使用@RequestMapping修饰的方法
这里就是使用RequestMappingHandlerAdapter,去处理这个服务请求,实现起来肯定还是比较复杂,这里不垒代码了,想知道细节的可以去源码看。 - 实现了Servlet接口
这里就是使用SimpleServletHandlerAdapter
public class SimpleServletHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof Servlet);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
((Servlet) handler).service(request, response);
return null;
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
return -1;
}
}
- 实现了Controller接口
这里就是使用SimpleControllerHandlerAdapter
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
网友评论