责任链模式
2020-03-08 本文已影响0人
GeekerLou
责任链模式
责任链模式的优缺点
责任链模式与if…else…相比,他的耦合性要低一些,因为它把条件判定都分散到了各个处理类中,并且这些处理类的优先处理顺序可以随意设定。责任链模式也有缺点,这与if…else…语句的缺点是一样的,那就是在找到正确的处理类之前,所有的判定条件都要被执行一遍,当责任链比较长时,性能问题比较严重。
责任链模式的适用场景
假如使用if…else…语句来组织一个责任链时感到力不从心,代码看上去很糟糕时,就可以使用责任链模式来进行重构。
示例
定义一个处理优先级类Level
public class Level {
private int level = 0;
public Level(int level) {
this.level = level;
}
public boolean above(Level level) {
if (this.level >= level.level) {
return true;
}
return false;
}
}
模拟一个处理请求Request类,该类会包含有处理优先级类,以提示后面的处理器
public class Request {
Level level;
public Request(Level level) {
this.level = level;
}
public Level getLevel() {
return level;
}
}
模拟响应类Response
public class Response {
}
定义一个抽象的处理抽象类Handler,之所有使用抽象类而不是纯接口在于抽象类可以包含一些默认的实现方法,对于确定的处理过程我们可以将其写到抽象类的具体实现中,而对于每个处理器都不一样的,这里我们只定义一个抽象方法,由具体的实现类去做具体的特定实现:
public abstract class Handler {
public final Response handleRequest(Request request, FilterChain chain) {
Response response = null;
if (this.getHandlerLevel().above(request.getLevel())) {
response = this.response(request);
} else {
chain.doFilter(request);
}
return response;
}
protected abstract Level getHandlerLevel();
public abstract Response response(Request request);
}
处理器1 ConcreteHandler1:
public class ConcreteHandler1 extends Handler{
@Override
protected Level getHandlerLevel() {
return new Level(1);
}
@Override
public Response response(Request request) {
System.out.println("-----请求由处理器1进行处理-----");
return null;
}
}
处理器2 ConcreteHandler2:
public class ConcreteHandler2 extends Handler {
@Override
protected Level getHandlerLevel() {
return new Level(3);
}
@Override
public Response response(Request request) {
System.out.println("-----请求由处理器2进行处理-----");
return null;
}
}
处理器3 ConcreteHandler3:
public class ConcreteHandler3 extends Handler{
@Override
protected Level getHandlerLevel() {
return new Level(5);
}
@Override
public Response response(Request request) {
System.out.println("-----请求由处理器3进行处理-----");
return null;
}
}
接下来出场是最关键的串联类FilterChain,通过它我们来串联上面提到的各个Handler:
import org.springframework.util.CollectionUtils;
import java.util.List;
public class FilterChain {
private int pos = 0;
private List<Handler> handlerList;
public FilterChain(List<Handler> handlerList) {
this.handlerList = handlerList;
}
/**
* 洋葱模型,处理后能够返回
*
* @param request
* @return
*/
public Response doFilter(Request request) {
if (!CollectionUtils.isEmpty(handlerList) && pos < handlerList.size()) {
System.out.println(String.format("the %d time for processing", pos + 1));
return handlerList.get(pos++).handleRequest(request, this);
}
return null;
}
}
OK,接下来写个单测试一下:
import com.netease.learn.designPattern.fliterChain.*;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
/**
* 责任链模式测试类
*/
public class FliterChainTest {
@Test
public void test() {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
List<Handler> handlerList = Arrays.asList(handler1, handler2, handler3);
FilterChain filterChain = new FilterChain(handlerList);
filterChain.doFilter(new Request(new Level(4)));
}
}
备注:
- 在实际的工程中,我们通常在Spring 的XML文件中去初始化各个chain,然后将他们的实例注入到FilterChain中。
输出如下:
the 1 time for processing
the 2 time for processing
the 3 time for processing
-----请求由处理器3进行处理-----