携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
基本介绍
1)创建一个接收者对象的链,如果一个对象不能处理该请求,怎会传递至下一个对象处理,依次类推
2)属于行为型模式
3)能够使接收者和发送者有效的解耦,对于接收者一端有利于扩展
责任链模式的注意事项和细节
1)客户端只需将请求发送到链上即可,无须关心请求的处理细节和请求的传递。
2)拦截类都实现统一接口
3)优点:(1)降低耦合度 (2)简化了对象 (3)增强给对象指派职责的灵活性 (4)有利于接收者的扩展性
4)缺点:(1)如果一个对象可以由多个接收者处理,具体哪个接收者处理取决于运行时自动确定
类图
案例代码
package com.example.demo.design.chain;
public abstract class Handler {
abstract void hanleRequest(String request);
protected Handler handler;
public void setSuccessor(Handler handler){
this.handler = handler;
}
public Handler getSuccessor(){
return handler;
}
}
package com.example.demo.design.chain;
public class DeptManager extends Handler{
@Override
void hanleRequest(String request) {
if("dept".equals(request)){
System.out.println("DeptManager 处理请求");
}else {
if(getSuccessor() != null){
getSuccessor().hanleRequest(request);
}else{
System.out.println(request + " 没有处理的类型类");
}
}
}
}
package com.example.demo.design.chain;
public class GeneralManager extends Handler{
@Override
void hanleRequest(String request) {
if("general".equals(request)){
System.out.println("GeneralManager 处理请求");
}else {
if(getSuccessor() != null){
getSuccessor().hanleRequest(request);
}else{
System.out.println(request + " 没有处理的类型类");
}
}
}
}
package com.example.demo.design.chain;
public class ProjectManager extends Handler{
@Override
void hanleRequest(String request) {
if("project".equals(request)){
System.out.println("ProjectManager 处理请求");
}else {
if(getSuccessor() != null){
getSuccessor().hanleRequest(request);
}else{
System.out.println(request + " 没有处理的类型类");
}
}
}
}
package com.example.demo.design.chain;
public class Client {
public static void main(String[] args) {
//组装责任链
Handler handler1 = new DeptManager();
Handler handler2 = new GeneralManager();
Handler handler3 = new ProjectManager();
handler1.setSuccessor(handler2);
handler2.setSuccessor(handler3);
handler1.hanleRequest("general");
System.out.println("----------");
handler1.hanleRequest("dept");
System.out.println("----------");
handler1.hanleRequest("project");
System.out.println("----------");
handler1.hanleRequest("12312");
}
}
结果
责任链模式在Spring MVC 的 DispatcherServlet 类中的应用
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
ModelAndView mv = null;
Exception dispatchException = null;
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
spring mvc执行流程
1、用户发起请求---->DispatcherServlet ,收到请求后不解析,委托给其他解析器进行处理。
2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、View——>渲染,View会根据传进来的Model模型数据进行渲染(将数据添加到页面),此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。