责任链模式最基础的版本,一个Interface或者抽象类,多个具体实现类,一个责任链管理类。写出来的代码层级。
// 定义请求类
class Request {
private final int requestLevel;
public Request(int level) {
this.requestLevel = level;
}
public int getRequestLevel() {
return requestLevel;
}
}
// 定义抽象处理者类
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(Request request);
}
// 具体处理者类 1
class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getRequestLevel() <= 1) {
System.out.println("ConcreteHandler1 处理了请求");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理者类 2
class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getRequestLevel() <= 2) {
System.out.println("ConcreteHandler2 处理了请求");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理者类 3
class ConcreteHandler3 extends Handler {
@Override
public void handleRequest(Request request) {
if (request.getRequestLevel() <= 3) {
System.out.println("ConcreteHandler3 处理了请求");
} else {
System.out.println("没有处理者能处理该请求");
}
}
}
// 客户端类
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
// 创建处理者
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
// 设置处理者链
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
// 创建请求
Request request1 = new Request(1);
// 发送请求
handler1.handleRequest(request1);
}
}
我们日常的实际项目都是基于spring去开发,那么结合spring做优化。
优化1:
实现自动注入,在spring启动时就已经创建好链。可以新增一个manager类通过实现ApplicationContextAware接口或者使用@Autowired注册。
@Component
public class ChainManager {
private final List<Handler> handlers;
@Autowired
public ChainManager(List<Handler> handlers) {
this.handlers = handlers;
}
public Handler getFirstHandler() {
return handlers.isEmpty() ? null : handlers.get(0);
}
}
那么这里又有个问题,责任链的顺序怎么指定。可以通过@Order执行下每个具体实现类的加载顺序。或者在抽象类中再增加一个抽象方法,指定顺序。
优化二:把这个模式做成通用的请求报文处理。那就再加一个新的context。用于获取上下文所有可支持的请求处理。
@Data
public class ReqContext<T> {
private Request request;
private List<T> resultVO=new ArrayList<>();
private String result;
}