网站首页 > 精选教程 正文
概述
维基百科将责任链定义为一种由“一个命令对象源和一系列处理对象”组成的设计模式。
链中的每个处理对象都负责特定类型的命令,处理完成后,它将命令转发给链中的下一个处理器。
责任链模式适用于:
- 让命令发送器和接收器解耦
- 在处理命令时选择处理策略
示例
我们将使用责任链来创建一个用于处理身份验证请求的链。
输入身份验证提供程序将是命令,每个身份验证处理器将是一个单独的处理器对象。
首先为处理器创建一个抽象基类:
public abstract class AuthenticationProcessor {
public AuthenticationProcessor nextProcessor;
// standard constructors
public abstract boolean isAuthorized(AuthenticationProvider authProvider);
}
接下来,创建具体的处理器来扩展AuthenticationProcessor:
public class OAuthProcessor extends AuthenticationProcessor {
public OAuthProcessor(AuthenticationProcessor nextProcessor) {
super(nextProcessor);
}
@Override
public boolean isAuthorized(AuthenticationProvider authProvider) {
if (authProvider instanceof OAuthTokenProvider) {
return true;
} else if (nextProcessor != null) {
return nextProcessor.isAuthorized(authProvider);
}
return false;
}
}
public class UsernamePasswordProcessor extends AuthenticationProcessor {
public UsernamePasswordProcessor(AuthenticationProcessor nextProcessor) {
super(nextProcessor);
}
@Override
public boolean isAuthorized(AuthenticationProvider authProvider) {
if (authProvider instanceof UsernamePasswordProvider) {
return true;
} else if (nextProcessor != null) {
return nextProcessor.isAuthorized(authProvider);
}
return false;
}
}
为传入的授权请求创建了两个具体的处理器:UsernamePasswordProcessor和OAuthProcessor。每一个处理器都会重写isAuthorized方法。
创建几个测试用例:
public class ChainOfResponsibilityTest {
private static AuthenticationProcessor getChainOfAuthProcessor() {
AuthenticationProcessor oAuthProcessor = new OAuthProcessor(null);
return new UsernamePasswordProcessor(oAuthProcessor);
}
@Test
public void givenOAuthProvider_whenCheckingAuthorized_thenSuccess() {
AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor();
assertTrue(authProcessorChain.isAuthorized(new OAuthTokenProvider()));
}
@Test
public void givenSamlProvider_whenCheckingAuthorized_thenSuccess() {
AuthenticationProcessor authProcessorChain = getChainOfAuthProcessor();
assertFalse(authProcessorChain.isAuthorized(new SamlTokenProvider()));
}
}
上面的示例创建了一个身份验证处理器链:UsernamePasswordProcessor->OAuthProcessor。
首先,UsernamePasswordProcessor检查身份验证提供程序是否是UsernamePasswordProvider的实例,UsernamePasswordProcessor不是预期的输入,而是委托给OAuthProcessor。最后,OAuthProcessor处理该命令。
实施原则
在实施责任链时,需要牢记以下几个重要原则:
- 链中的每个处理器都有其处理命令的实现:在上面的例子中,所有处理器都实现了isAuthorized
- 链中的每个处理器都应该引用下一个处理器:比如UsernamePasswordProcessor委托给OAuthProcessor
- 每个处理器都负责委派给下一个处理器,因此要小心丢弃的命令:同样在示例中,如果命令是SamlProvider的实例,那么该请求可能不会得到处理,并且将是未经授权的
- 处理器不应形成递归循环:在例子中,链中没有出现循环:UsernamePasswordProcessor->OAuthProcessor
- 链中只有一个处理器处理给定的命令:在示例中,如果传入命令包含OAuthTokenProvider的实例,那么只有OAuthProcessor将处理该命令
Spring框架中的实际用例
Java中的Servlet过滤器就是这样一个经典的例子,它允许多个过滤器处理一个HTTP请求。每个过滤器需要调用FilterChain的doFilter方法,以便将请求传递给链中的下一个处理器。
public class CustomFilter implements Filter {
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// process the request
// pass the request (i.e. the command) along the filter chain
chain.doFilter(request, response);
}
}
结论
责任链模式对于链式命令处理非常有用,不过也有一些缺点:
- 如果某个处理器无法调用下一个处理器,则该命令将被丢弃
- 如果处理器调用错误的处理器,可能会导致循环
- 可能创建深度堆栈跟踪,从而影响性能
- 上一篇: 在框架中随处可见的责任链模式原理就是这么简单
- 下一篇: 设计模式之责任链模式
猜你喜欢
- 2024-12-02 面试官:项目中你是如何利用设计模式,干掉if-else的
- 2024-12-02 设计模式——职责链模式
- 2024-12-02 梳理原理,这一次就彻底了解OkHttp与Retrofit吧
- 2024-12-02 同事写了一个责任链模式,bug无数...
- 2024-12-02 设计模式之不一样的责任链模式
- 2024-12-02 如何在业务代码中优雅的使用责任链模式
- 2024-12-02 设计模式系列-行为型-责任链模式
- 2024-12-02 责任链模式(Chain of Responsibility Pattern)
- 2024-12-02 设计模式系列—责任链模式
- 2024-12-02 设计模式之责任链模式
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)