设计模式之适配器模式(六)

一、概念

将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作。

二、Spring MVC 中的适配器模式

1、面临的问题
Spring MVC 中Controller的类型不同,类型不同,调用的方式就不确定。
①实现Controller的接口

public class ControllerDemo1 implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        System.out.println("===方式一:实现Controller接口===");
        //使用ModelAndView去响应
        ModelAndView mav = new ModelAndView();//模型数据和视图对象
        mav.addObject("msg","helloworld");//添加模型数据
        mav.setViewName("/hello.jsp");//设置视图路径      是一个转发
        return mav;
    }
}

Spring MVC配置:

<bean id="/demo1" class="com.zhengqing.controller.ControllerDemo1" ></bean>

②实现HttpRequestHandler接口

public class ControllerDemo2 implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("===实现HttpRequestHandler接口===");
    }
}

Spring MVC配置:

<bean id="/demo2" class="com.zhengqing.controller.ControllerDemo2" ></bean>

③直接就是一个普通JAVA类 (使用注解的方式,注意:要配置全注解!!)

@Controller   //创建对象
//@RequestMapping("/demo")
public class ControllerDemo3 {
    @RequestMapping("/demo3")  //配置访问路径  注意:如果类上面添加了@RequestMapping("/demo")  则此时访问将变成/demo/demo3
    @ResponseBody
    public void test(){
        System.out.println("方式三:普通类+注解");
    }
}

在SpringMVC的配置中添加自动扫描(作用:让spring管理这个bean即可,无需指定路径,在方法上面通过@RequestMapping指定即可!)

<!-- 全注解扫描所有的包 -->
<context:component-scan base-package="com.zhengqing.controller" />

如果直接调用controller方法,则会出现如下情况

if(mappedHandler.getHandler() instanceof MultiActionController){  
   ((MultiActionController)mappedHandler.getHandler()).xxx  
}else if(mappedHandler.getHandler() instanceof XXX){  
    ...  
}else if(...){  
   ...  
}

这样假设如果我们增加一个HardController,就要在代码中加入一行 if(mappedHandler.getHandler() instanceof HardController)
这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 -- 对扩展开放,对修改关闭。

2、解决方式
因此Spring定义了一个\color{red}{适配接口},使得每一种Controller有一种对应的适配器实现类, 让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了,真的是很精巧的做法!

三、实例代码解析

以下是三种Controller实现

public interface Controller {  
  
}  
  
public class HttpController implements Controller{  
    public void doHttpHandler(){  
        System.out.println("http...");  
    }  
}  
  
public class SimpleController implements Controller{  
    public void doSimplerHandler(){  
        System.out.println("simple...");  
    }  
}  
  
public class AnnotationController implements Controller{  
    public void doAnnotationHandler(){  
        System.out.println("annotation...");  
    }  
} 

定义一个Adapter接口

public interface HandlerAdapter {  
    public boolean supports(Object handler);  
    public void handle(Object handler);  
}

下面编写适配器类

public class SimpleHandlerAdapter implements HandlerAdapter {  
  
  
    public void handle(Object handler) {  
        ((SimpleController)handler).doSimplerHandler();  
    }  
  
    public boolean supports(Object handler) {  
        return (handler instanceof SimpleController);  
    }  
  
}  
  
  
public class HttpHandlerAdapter implements HandlerAdapter {  
  
    public void handle(Object handler) {  
        ((HttpController)handler).doHttpHandler();  
    }  
  
    public boolean supports(Object handler) {  
        return (handler instanceof HttpController);  
    }  
  
}  
  
  
  
public class AnnotationHandlerAdapter implements HandlerAdapter {  
  
    public void handle(Object handler) {  
        ((AnnotationController)handler).doAnnotationHandler();  
    }  
  
    public boolean supports(Object handler) {  
          
        return (handler instanceof AnnotationController);  
    }  
  
}  

模拟一个DispatcherServlet

public class DispatchServlet {  
      
    public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();   
      
    public DispatchServlet(){  
        handlerAdapters.add(new AnnotationHandlerAdapter());  
        handlerAdapters.add(new HttpHandlerAdapter());  
        handlerAdapters.add(new SimpleHandlerAdapter());  
    }  
      
      
    public void doDispatch(){  
          
        //此处模拟SpringMVC从request取handler的对象,仅仅new出,可以出,               
                     //不论实现何种Controller,适配器总能经过适配以后得到想要的结果  
//      HttpController controller = new HttpController();  
//      AnnotationController controller = new AnnotationController();  
        SimpleController controller = new SimpleController();  
        //得到对应适配器  
        HandlerAdapter adapter = getHandler(controller);  
        //通过适配器执行对应的controller对应方法  
        adapter.handle(controller);  
          
    }  
      
    public HandlerAdapter getHandler(Controller controller){  
        for(HandlerAdapter adapter: this.handlerAdapters){  
            if(adapter.supports(controller)){  
                return adapter;  
            }  
        }  
        return null;  
    }  
      
    public static void main(String[] args){  
        new DispatchServlet().doDispatch();  
    }  
      
}  
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容