职责链模式(Chain of Responsibility)
职责链模式:
该模式避免了请求与多个处理者之间的耦合。说直白点,就是从多个处理者中选择一个,我们平时的想法是if else判断,但当处理者过多的时候就过于复杂,且增加或删除处理者,会改变业务代码,不满足开闭原则。
文章图片
从结构图可以看出,我们对处理者与处理者之间指定了顺序,如果该处理者处理不了就交给下一个。当处理者之间的顺序不要求的时候也可以直接用集合代替。
下面以SpringMVC中的doDispatch方法中,getHandlerAdapter方法对职责链进行分析。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
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 || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
文章图片
【职责链模式(Chain of Responsibility)】下面见上述流程简述一下:
文章图片
MVC根据外部请求取到合适的handler,再通过handler寻找合适的adapter,那怎么寻找呢?这里用到了职责链模式
定义HandlerAdapter接口:
public interface HandlerAdapter {
//是否支持该handler
boolean supports(Object handler);
//请求处理
void handler();
}
具体的适配器实现HandlerAdapter接口:
public class AnnotationMethodHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof AnnotationMethodHandler);
}
@Override
public void handler() {
System.out.println("请求交给AnnotationMethodHandlerAdapter处理");
}
}
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof RequestMappingHandler);
}
@Override
public void handler() {
System.out.println("请求交给RequestMappingHandlerAdapter处理");
}
}
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof SimpleControllerHandler);
}
@Override
public void handler() {
System.out.println("请求交给SimpleControllerHandlerAdapter处理");
}
}
用户使用时:
public class Main {
public static void main(String[] args) {
//前期预处理,假设链上有这三种adapter
List handlerAdapterList = new ArrayList<>();
handlerAdapterList.add(new RequestMappingHandlerAdapter());
handlerAdapterList.add(new SimpleControllerHandlerAdapter());
handlerAdapterList.add(new AnnotationMethodHandlerAdapter());
//假如请求的handler为RequestMappingHandler
RequestMappingHandler handler = new RequestMappingHandler();
//根据职责链匹配查找,这里没有指定职责链的顺序,也是可以的
for (HandlerAdapter ha : handlerAdapterList) {
if (ha.supports(handler)) {
ha.handler();
}
}
}
}
文章图片
这样,当RequestMappingHandler时,会找到合适的适配器,并交给它处理了。当增加适配器的时候,只要增加处理类,不需要修改业务代码。
for (HandlerAdapter ha : handlerAdapterList) {
if (ha.supports(handler)) {
ha.handler();
}
}
推荐阅读
- 画解算法(1.|画解算法:1. 两数之和)
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 「#1-颜龙武」区块链的价值是什么()
- leetcode|leetcode 92. 反转链表 II
- BNC公链|BNC公链 | Eth2.0测试网Topaz已质押超100万枚ETH
- 【#2-戴栋】区块链可以提升哪些商业上的效率改进
- --木木--|--木木-- 第二课作业#翼丰会(每日一淘6+1实战裂变被动引流# 6+1模式)
- 设计模式-代理模式-Proxy
- 父母链接八~未了情结
- 【译】Rails|【译】Rails 5.0正式发布(Action Cable,API模式等)