责任链模式,简单说就是在所有逻辑的链式执行,在订单业务中,需要满足各种条件才能下单成功;http请求中,需要满足参数校验,数据转换,各类验证后才可以执行真正的业务逻辑。类似与需要满足很多条件才能执行成功的业务,很自然的就会想到责任链模式。责任链模式的概念参考《大话设计模式》的责任链模式模块。
参考spring,tomcat各类源码,在实际实现中有个常规的设计和实现方式。定义接口过滤器接口Filter,执行真正的过滤逻辑;过滤器链接口FilterChain,控制执行下一个过滤器;过滤器管道接口FilterPipeline,定义所有的过滤器执行逻辑。如果需要新增新的过滤条件,直接自定义Filter逻辑,添加到FilterPipeline中就可以实现过滤器动态的扩展。接口定义如下:
/**
* 过滤器
**/
public interface Filter {
/**
* 过滤
*
* @param param
* @param filterChain 过滤器链
* @throws BusinessException
*/
void doFilter(Object param, FilterChain filterChain) throws BusinessException;
}
/**
* 过滤器链
**/
public interface FilterChain {
/**
* @param param
* @throws BusinessException
*/
void doFilter(Object param) throws BusinessException;
}
/**
* 过滤器管道
**/
public interface FilterPipeline {
/**
* @param param
* @throws BusinessException
*/
void doFilter(Object param) throws BusinessException;
}
在实际代码中,实现FilterPipeline 定义所有的过滤器管道,在该实现类实现FilterChain的内部类实现,定义过滤器链执行下一个过滤器的执行逻辑。定义了内部成员变量,List<Filter> filters; 设置所有需要执行过滤的过滤器数据,该List中的过滤器可以对Filter实现类在实现spring 的Ordered接口,对过滤顺序进行顺序调整。FilterPipeline 实现类实现如下,如下:
/**
* 过滤器list
*/
private List<Filter> filters;
/**
* 初始化
*/
private void init() {
this.filters = Lists.newArrayList(new MaxTotalFilter());
// 对实现了Ordered 的实现类排序
AnnotationAwareOrderComparator.sort(filters);
}
/**
* 过滤器pipline方法实现
*/
@Override
public void doFilter(Object param) throws BusinessException {
if (CollectionUtils.isEmpty(filters)) {
return;
}
new ExcelFilterChain(0, filters).doFilter(param);
}
FilterChain的内部类自定义代码如下:
private static class ExcelFilterChain implements FilterChain {
private int currentIndex;
private List<Filter> filters;
public ExcelFilterChain(int currentIndex, List<Filter> filters) {
this.currentIndex = currentIndex;
this.filters = filters;
}
@Override
public void doFilter(Object rowData) throws BusinessException {
if (currentIndex < 0
|| CollectionUtils.isEmpty(filters)
|| currentIndex >= filters.size()) {
return;
}
Filter filter = filters.get(currentIndex);
currentIndex++;
filter.doFilter(rowData, this);
}
}
自定义过滤器实现类如下:
/**
* 最大数量过滤
**/
@Slf4j
public class MaxTotalFilter implements Filter, Ordered {
@Override
public void doFilter(Object pram, FilterChain filterChain) throws BusinessException {
if (notMatch(pram)) {
filterChain.doFilter(pram);
return;
}
// 该过滤器的真正执行逻辑
// TODO
// 执行链式的下一个过滤器
filterChain.doFilter(pram);
}
/**
* 不满足条件的逻辑
*
* @param pram
* @return
*/
private boolean notMatch(Object pram) {
return true;
}
@Override
public int getOrder() {
return 0;
}
}