一.基本框架

如上图所示,责任链的由节点(实现了ValidatorHandler接口)和主流程(负责组装各个节点)组成.
其实现方式一共有两种:
- 数组:如上图所示,在Validator中通过List将各个节点存储起来.
- 链表: 在各个节点中存储next,并提供appNext(ValidatorHandler handler)方法供Validator装配使用.
二. 引入上下文
在责任连中引入上下文,对外不可见,只对责任链的主流程和各个节点可见;可以方便存储每个节点过滤的信息,同时,也便于对主流程序进行干预
1. 升级1:责任链的所有节点全部执行
需求:在责任链的基本实现中,当前面节点抛出异常,后面节点便不会再执行,如果需要责任链全部执行完然后再抛出全部的异常,如何进行?
方案1:不引入上下文,在主流程中直接捕获异常存储起来,当节点全部执行完毕后,再抛出异常.
java
public class ValidatorChain {
private final List<ValidatorHandler> handlers = new ArrayList<>();
public void validate(Object value) {
//存储异常信息
List<String> list = new ArrayList<>();
for (ValidatorHandler handler : handlers) {
try {
handler.validate(value, context);
}catch (ValidatorException e){
list.add(e.getMessage());
}
}
if (list.isEmpty()) {
return;
}
throw new ValidatorException(list.toString());
}
}
方案2:引入上下文,节点不再抛出异常,直接将异常信息存储在上下文中,执行完全部节点后再抛出异常
java
public class ValidatorContext {
private final List<String> errorMessageList = new ArrayList<>();
public void appendError(String message) {
errorMessageList.add(message);
}
public void throwExceptionIfNecessary() {
if(errorMessageList.isEmpty()){
return;
}
throw new ValidatorException(errorMessageList.toString());
}
}
java
public class ValidatorChain {
private final List<ValidatorHandler> handlers = new ArrayList<>();
public void validate(Object value) {
ValidatorContext context = new ValidatorContext();
for (ValidatorHandler handler : handlers) {
handler.validate(value, context);
if(context.isStopped()){
break;
}
}
context.throwExceptionIfNecessary();
}
}
2. 升级2:节点干预主流程
需求: 在升级1的基础上,如何实现节点控制当主流程的进行?
解决方案:在上下文中引入stopped变量,如果某一个节点想要中断流程,则调用上下文的stopChain()方法,同时在主流程中执行完该节点后取出上下文的stopChain方法判断主流成是否中断
上下文
java
public class ValidatorContext {
private final List<String> errorMessageList = new ArrayList<>();
private boolean stopped =false;
private int currentIndex = 0;
public void stopChain(){
this.stopped =true;
}
public boolean isStopped(){
return stopped;
}
public void throwExceptionIfNecessary() {
if(errorMessageList.isEmpty()){
return;
}
throw new ValidatorException(errorMessageList.toString());
}
}
主流程:
java
public class ValidatorChain {
private final List<ValidatorHandler> handlers = new ArrayList<>();
public void validate(Object value) {
ValidatorContext context = new ValidatorContext();
for (ValidatorHandler handler : handlers) {
handler.validate(value, context);
if(context.isStopped()){
break;
}
}
context.throwExceptionIfNecessary()
}
public void addLastHandler(ValidatorHandler handler) {
this.handlers.add(handler);
}
}
节点:
java
public class MaxValidatorHandler implements ValidatorHandler{
private final int max;
public MaxValidatorHandler(int max) {
this.max = max;
}
@Override
public void validate(Object value,ValidatorContext context) {
if(value instanceof Integer integerValue){
if(integerValue > max){
context.appendError("你的值是"+ integerValue+ "不能大于"+max);
context.stopChain();
}
}
}
}