责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,它允许将请求沿着处理者链进行传递。每个处理者都可以对请求进行处理,或者将其传递给链中的下一个处理者。责任链模式通过将多个处理者连接成一条链,使得请求可以在链中传递,直到某个处理者处理它为止。
模式结构
- 处理者接口(Handler)
定义处理请求的接口,通常包含一个处理请求的方法和一个设置下一个处理者的方法。 - 具体处理者(Concrete Handler)
实现处理者接口,负责处理请求。如果当前处理者无法处理请求,则将其传递给链中的下一个处理者。 - 调用者(Client)
创建责任链,并将请求发送给链中的第一个处理者。
代码示例
1. 处理者接口(Handler)
// 处理者接口:定义处理请求的接口
abstract class Middleware {
private Middleware next;
// 设置下一个处理者
public Middleware linkWith(Middleware next) {
this.next = next;
return next;
}
// 处理请求的方法
public abstract Boolean check(String name, String password);
// 将请求传递给下一个处理者
protected Boolean checkNext(String name, String password) {
if (next == null) {
return true;
}
return next.check(name, password);
}
}
2. 具体处理者(Concrete Handler)
// 具体处理者:限制流量
class ThrottlingMiddleware extends Middleware {
private final int requestPerMinute;
private int request;
private long currentTime;
public ThrottlingMiddleware(int requestPerMinute) {
this.requestPerMinute = requestPerMinute;
this.currentTime = System.currentTimeMillis();
}
@Override
public Boolean check(String name, String password) {
if (System.currentTimeMillis() > currentTime + 60_000) {
request = 0;
currentTime = System.currentTimeMillis();
}
request++;
if (request > requestPerMinute) {
System.out.println("请求次数超过限制.");
return false;
}
return checkNext(name, password);
}
}
// 具体处理者:检查用户是否存在
class UserExistsMiddleware extends Middleware {
private final Server server;
public UserExistsMiddleware(Server server) {
this.server = server;
}
@Override
public Boolean check(String user, String password) {
if (!server.hasUser(user)) {
System.out.println("该用户未注册!");
return false;
}
if (!server.isValidPassword(user, password)) {
System.out.println("密码错误!");
return false;
}
return checkNext(user, password);
}
}
// 具体处理者:检查用户角色
class RoleCheckMiddleware extends Middleware {
@Override
public Boolean check(String user, String password) {
if ("root".equals(user) || "admin".equals(user)) {
System.out.println("Hello admin!");
return true;
}
System.out.println("Hello user!");
return checkNext(user, password);
}
}
3.示例代码
public class ChainOfResponsibilityPattern {
private static Server server;
private static void init() {
server = new Server();
server.register("admin", "admin");
server.register("root", "admin");
server.register("jack", "heel");
// 创建责任链
Middleware middleware = new ThrottlingMiddleware(2);
middleware.linkWith(new UserExistsMiddleware(server)).linkWith(new RoleCheckMiddleware());
server.setMiddleware(middleware);
}
public static void main(String[] args) {
init();
boolean success;
Scanner in = new Scanner(System.in);
do {
System.out.print("Enter user :");
String user = in.nextLine();
System.out.print("Input password : ");
String password = in.nextLine();
success = server.login(user, password);
} while (!success);
}
}
输出结果
Enter user :admin
Input password : admin
Hello admin!
认证通过,用户登录成功!
应用场景
- 多条件处理
当程序需要根据不同的条件处理请求,且请求的处理顺序和条件未知时,可以使用责任链模式。 - 动态处理顺序
当需要在运行时动态调整处理者的顺序时,可以使用责任链模式。 - 解耦请求和处理者
当需要将请求的发送者和处理者解耦时,可以使用责任链模式。
在Java中的应用
javax.servlet.Filter
Java Servlet 中的过滤器链(Filter Chain)就是责任链模式的一个典型应用。每个过滤器都可以对请求进行处理,或者将其传递给下一个过滤器。java.util.logging.Logger
Java 的日志框架中,日志记录器(Logger)可以将日志消息传递给父记录器,形成一条责任链。
优缺点
优点
- 解耦请求和处理者
责任链模式将请求的发送者和处理者解耦,使得请求可以在链中传递,直到某个处理者处理它。 - 动态调整处理顺序
责任链模式允许在运行时动态调整处理者的顺序,增加了系统的灵活性。 - 单一职责原则
每个处理者只负责处理自己关心的请求,符合单一职责原则。
缺点
- 请求可能未被处理
如果责任链配置不当,请求可能会传递到链的末端而未被处理。 - 性能问题
责任链模式可能会导致请求在链中传递多次,增加了系统的性能开销。
总结
责任链模式通过将多个处理者连接成一条链,使得请求可以在链中传递,直到某个处理者处理它为止。它适用于需要根据不同的条件处理请求的场景,尤其是在请求的处理顺序和条件未知时。尽管它可能会增加系统的复杂性,但其优点在于提高了代码的灵活性和可扩展性。在Java中,责任链模式广泛应用于Servlet过滤器和日志框架等场景。