简介
责任链模式又称职责链模式,是行为型模式的一种。责任链模式是23种设计模式种较难的一种,在一些大型的框架中就有责任链的身影,如Tomcat容器的过滤器,SpringMVC的拦截器等等。责任链的核心就是在系统中有多个任务处理者,对于某一个事件,每个处理者会判断自己能不能处理,如果能则处理,不能则往下传,直到有人处理为止。责任链就好像我们公司的审批一样,有的审批小组长就可以搞定,有的审批需要到部门老大那里,有的需要到部门经理那里,如果前面都不能处理,最后会流到老板那里。其实现有两种:第一种是传统的实现,在处理者中指定下一个处理者,第二种是将所有处理者放到一个list中,此时加入的顺序就很重要了。接下来就分别对这两种做代码示例。
传统实现
假设我们是一个出版社,收到了一个投稿文章,此时我们有格式审核部门、文字审核部门和最终专家质量审核。当我们比较闲时,会先审核格式,然后再去审核文字是否有敏感词汇和错别字,完了交给专家审核,最后将所有审核意见返回给作者。
1.定义一个Handler抽象类,然后FormatHandler/WordHandler/QualityHandler继承Handler
public abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract String handRequest(String content);
}
public class FormatHandler extends Handler{
@Override
public String handRequest(String content) {
String formatContent = checkFormatMsg(content);
if (null != this.nextHandler) {
return this.nextHandler.handRequest(formatContent);
}
return formatContent;
}
private String checkFormatMsg(String content) {
System.out.println("Check format");
return content + "->checkFormat";
}
}
public class WordHandler extends Handler{
@Override
public String handRequest(String content) {
String newContent = checkError(content);
if (null != this.nextHandler) {
return this.nextHandler.handRequest(newContent);
}
return newContent;
}
private String checkError(String content) {
System.out.println("Check error");
return content + "->checkError";
}
}
public class QualityHandler extends Handler {
@Override
public String handRequest(String content) {
String newContent = checkQuality(content);
if (null != this.nextHandler) {
return this.nextHandler.handRequest(newContent);
}
return newContent;
}
private String checkQuality(String content) {
System.out.println("Check quality");
return content + "->checkQuality";
}
}
2.客户端调用
public class Test {
public static void main(String[] args) {
Handler formatHandler = new FormatHandler();
Handler errorHandler = new WordHandler();
Handler qualityHandler = new QualityHandler();
formatHandler.setNextHandler(errorHandler);
errorHandler.setNextHandler(qualityHandler);
System.out.println(formatHandler.handRequest("hello world"));
/**
* Check format
* Check error
* Check quality
* hello world->checkFormat->checkError->checkQuality
*/
}
}
使用list实现
接上面的场景,当我们现在很忙时,我们的步骤就是首先审核格式,如果格式有问题直接返回,错别字审核和质量审核以此类推。
1.定义一个IRequest接口,然后ContentRequest接口实现它,该接口主要时用于存储和获取事件在链中处理时的数据。
public interface IRequest {
void putEle(String key, Object value);
Object getEle(String key);
}
import java.util.HashMap;
import java.util.Map;
public class ContentRequest implements IRequest{
private Map<String, Object> request = new HashMap<>();
@Override
public void putEle(String key, Object value) {
request.put(key, value);
}
@Override
public Object getEle(String key) {
return request.getOrDefault(key, null);
}
}
2.定义IResponse接口,然后ContentResponse实现它,其主要作用时用于决定是否还需要向链的下游流去。
public interface IResponse {
boolean getEndStatus();
void setEndStatus(boolean end);
}
public class ContentResponse implements IResponse{
private boolean end = false;
@Override
public boolean getEndStatus() {
return end;
}
@Override
public void setEndStatus(boolean endStatus) {
this.end = endStatus;
}
}
3.定义Handler接口,然后FormatHandler/WordHandler/QualityHandler实现Handler
public class FormatHandler implements Handler{
@Override
public void hand(IRequest request, IResponse response) {
String content = (String)request.getEle("content");
if (content.contains("formatError")) {
response.setEndStatus(true);
request.putEle("endReason", "format error");
}
}
}
public class WordHandler implements Handler{
@Override
public void hand(IRequest request, IResponse response) {
String content = (String)request.getEle("content");
if (content.contains("wordError")) {
response.setEndStatus(true);
request.putEle("endReason", "word error");
}
}
}
public class QualityHandler implements Handler{
@Override
public void hand(IRequest request, IResponse response) {
String content = (String)request.getEle("content");
if (content.contains("qualityError")) {
response.setEndStatus(true);
request.putEle("endReason", "quality error");
}
}
}
4.定义一个执行引擎,用于创建和执行事件链
import java.util.ArrayList;
import java.util.List;
public final class HandlerEngine {
private final List<Handler> handlerChain = new ArrayList<>();
public void addHandler(Handler... handlers) {
for (Handler handler : handlers) {
handlerChain.add(handler);
}
}
public void executeHandler(IRequest request, IResponse response) {
for (Handler handler : handlerChain) {
handler.hand(request, response);
if (response.getEndStatus()) {
return;
}
}
}
}
5.客户端调用
public class Test {
public static void main(String[] args) {
String content1 = "formatError_quality1Error_word1Error";
String content2 = "format1Error_qualityError_word1Error";
String content3 = "format1Error_quality1Error_wordError";
String content4 = "format1Error_quality1Error_word1Error";
System.out.println(test(content1));//Paper not accept, reason of format error
System.out.println(test(content2));//Paper not accept, reason of quality error
System.out.println(test(content3));//Paper not accept, reason of word error
System.out.println(test(content4));//Paper accept
}
private static String test(String content) {
Handler formatHandler = new FormatHandler();
Handler wordHandler = new WordHandler();
Handler qualityHandler = new QualityHandler();
HandlerEngine engine = new HandlerEngine();
engine.addHandler(formatHandler, wordHandler, qualityHandler);
IRequest request = new ContentRequest();
request.putEle("content", content);
IResponse response = new ContentResponse();
engine.executeHandler(request, response);
String endReason = (String)request.getEle("endReason");
String res = null != endReason ? "Paper not accept, reason of " + endReason : "Paper accept";
return res;
}
}