课程大纲 / Lesson 12
Chain of Responsibility 行为型

Chain of Responsibility · 责任链

将请求的发送者和接收者解耦,让多个对象有机会处理这个请求。

01

理解责任链模式:将请求沿处理者链传递,直到某个处理者处理它

02

掌握 Handler(抽象处理者)与 ConcreteHandler(具体处理者)的链式结构

03

理解责任链的解耦特性:发送者无需知道谁来处理,请求自动沿链传递

04

了解责任链在认证链、日志链、过滤器、事件处理系统中的应用

核心概念
请求沿链传递发送者与接收者解耦Handler 链式结构选择性处理
classDiagram class middleware { <<abstract>> -next middleware +setnext(next middleware) middleware +check(email string,password string) boolean +checknext(email string,password string) boolean } class throttlingmiddleware { -requestcount int -threshold int$ -starttime long +check(email string,password string) boolean } class userexistsmiddleware { -server server +check(email string,password string) boolean } class rolecheckmiddleware { <<stateless>> +check(email string,password string) boolean } class server { -users hashmap~string,string~ -middleware middleware +use(middleware middleware) +login(email string,password string) boolean +hasemail(email string) boolean } middleware <|-- throttlingmiddleware middleware <|-- userexistsmiddleware middleware <|-- rolecheckmiddleware middleware o-- middleware : next server o-- middleware

请求沿处理者链依次传递,每个节点可以处理、拒绝或继续传递

点击 Run 执行认证链...
/** 抽象处理者:定义责任链接口 */
public abstract class Middleware {
    private Middleware next;

    public Middleware setNext(Middleware m) {
        next = m;
        return m;
    }

    public boolean check(String email, String password) {
        return checkNext(email, password);
    }

    protected boolean checkNext(String email, String password) {
        if (next == null) return true;
        return next.check(email, password);
    }
}
/** 限流中间件:检查请求频率是否超限 */
public class ThrottlingMiddleware extends Middleware {
    private int requestCount;
    private static final int THRESHOLD = 100;
    private long startTime = System.currentTimeMillis();

    public boolean check(String email, String password) {
        requestCount++;
        if (System.currentTimeMillis() - startTime > 60000) {
            requestCount = 0; startTime = System.currentTimeMillis();
        }
        if (requestCount > THRESHOLD) {
            System.out.println("ThrottlingMiddleware: Too many requests!");
            return false;
        }
        return checkNext(email, password);
    }
}
/** 用户存在检查中间件 */
public class UserExistsMiddleware extends Middleware {
    private Server server;

    public UserExistsMiddleware(Server server) {
        this.server = server;
    }

    public boolean check(String email, String password) {
        if (!server.hasEmail(email)) {
            System.out.println("UserExistsMiddleware: user not found");
            return false;
        }
        return checkNext(email, password);
    }
}
/** 角色检查中间件:验证管理员权限 */
public class RoleCheckMiddleware extends Middleware {
    public boolean check(String email, String password) {
        if (email.equals("admin@example.com")) {
            System.out.println("RoleCheckMiddleware: admin access granted");
            return checkNext(email, password);
        }
        System.out.println("RoleCheckMiddleware: regular user");
        return checkNext(email, password);
    }
}
import java.util.HashMap;

/** 服务器:持有中间件链,负责登录 */
public class Server {
    private HashMap<String, String> users = new HashMap<>();
    private Middleware middleware;

    public void use(Middleware m) { middleware = m; }

    public boolean login(String email, String password) {
        return middleware.check(email, password);
    }

    public boolean hasEmail(String email) {
        return users.containsKey(email);
    }
}
public class Demo {
    public static void main(String[] args) {
        Server server = new Server();
        Middleware m = new ThrottlingMiddleware();
        m.setNext(new UserExistsMiddleware(server))
         .setNext(new RoleCheckMiddleware());
        server.use(m);

        server.login("admin@example.com", "password");
    }
}
◈

发送者与接收者解耦

发送者(客户端)只需将请求发给链头,不需知道链上有谁、谁会处理;每个处理者只知道自己的下一个处理者。

◈

链式传递,请求自动流动

ThrottlingMiddleware → UserExistsMiddleware → RoleCheckMiddleware 依次检查,任一返回 false 即停止。

◈

灵活调整责任链

setNext() 支持运行时动态调整链的顺序和组成,新增/删除处理者无需修改已有代码,符合开闭原则。

◈

典型应用场景

Web 请求过滤(Spring Security Filter Chain)、日志级别处理(Logger Chain of Responsibility)、GUI 事件处理、Android View 事件分发。