责任链模式
责任链模式用于让多个处理器按顺序处理同一个请求,每个处理器决定自己是否处理,以及是否继续往后传。
一句话理解:请求沿着一条链往下走,谁能处理谁处理。
解决什么问题
业务中经常有一串校验或处理步骤:
text
参数校验 -> 登录校验 -> 权限校验 -> 风控校验 -> 执行业务如果全部写在一个方法里,代码会变得又长又难维护。责任链把每个步骤拆成独立处理器,再按顺序组合。
基本结构
text
Request -> Handler1 -> Handler2 -> Handler3角色:
Handler:处理器接口。ConcreteHandler:具体处理器。Chain:保存处理器顺序,并负责调用。
Java 示例
请求对象:
java
class LoginRequest {
private final String username;
private final String password;
LoginRequest(String username, String password) {
this.username = username;
this.password = password;
}
public String username() {
return username;
}
public String password() {
return password;
}
}处理器接口:
java
interface LoginHandler {
void handle(LoginRequest request);
}参数校验:
java
class ParamCheckHandler implements LoginHandler {
public void handle(LoginRequest request) {
if (request.username() == null || request.username().trim().isEmpty()) {
throw new IllegalArgumentException("username is required");
}
if (request.password() == null || request.password().trim().isEmpty()) {
throw new IllegalArgumentException("password is required");
}
}
}黑名单校验:
java
class BlacklistHandler implements LoginHandler {
public void handle(LoginRequest request) {
if ("blocked".equals(request.username())) {
throw new RuntimeException("user is blocked");
}
}
}责任链:
java
import java.util.List;
class LoginChain {
private final List<LoginHandler> handlers;
LoginChain(List<LoginHandler> handlers) {
this.handlers = handlers;
}
public void doFilter(LoginRequest request) {
for (LoginHandler handler : handlers) {
handler.handle(request);
}
}
}使用:
java
import java.util.Arrays;
LoginChain chain = new LoginChain(Arrays.asList(
new ParamCheckHandler(),
new BlacklistHandler()
));
chain.doFilter(new LoginRequest("justin", "123456"));使用场景
- Web 过滤器。
- 网关鉴权链路。
- 参数校验链。
- 风控规则链。
- 审批流程。
- 日志处理管道。
优点
- 每个处理器职责单一。
- 可以灵活调整顺序。
- 新增处理器不影响已有处理器。
- 适合流程步骤可插拔的场景。
缺点
- 链太长时排查困难。
- 顺序很重要,配置错误会导致行为异常。
- 请求可能没有被任何处理器处理。
- 如果每个处理器都依赖上下文,容易形成隐式耦合。
实战注意
责任链不一定要求“处理完就停止”。有些链是过滤器式的,每个节点都执行;有些链是审批式的,某个节点处理后就结束。设计前要先明确链的停止规则。