在本教程中,我们将学习如何在Java中实现责任链模式。
“责任链”设计模式涉及到拥有一系列负责处理请求的对象链。 当客户端发送请求时,第一个处理程序将尝试处理该请求。 如果可以处理,则请求处理在此结束。 但是,如果处理程序无法处理用户请求,则它将转到链中的下一个处理程序。 该过程将继续进行,直到链中的任何一个处理程序成功处理请求或链结束为止。 如果整个链条都无法处理该请求,则意味着该请求仍然无法满足。
为什么要使用责任链?
责任链是我们软件行业中非常重要的设计模式。 它具有以下优点:
- 由于用户不需要关心哪个对象将处理其请求,因此它促进了用户与系统之间的松散耦合。
- Java异常处理机制也利用了这种模式。 如果找不到合适的catch块,则将请求委托给调用方方法进行处理,直到找到合适的处理程序为止
- 通过让请求通过一系列过滤器,该模式还可以找到其在过滤用户请求中的应用程序
UML表示形式:
责任链模式的UML表示类似于:
在这里,我们具有以下类型的对象:
- 客户:发出用户请求的代码
- 处理程序: 抽象超类或定义请求处理程序方法的接口
- ConcreteHandler: Handler的实现类
处理程序对象在链中从一个连接到另一个。 而且, 每个具体处理程序都以其自己独特的方式处理请求。
定义抽象处理程序:
让我们使用责任链实现请求过滤逻辑。
首先,我们将定义一个抽象的RequestFilter类:
public abstract class RequestFilter { private RequestFilter next; public RequestFilter(RequestFilter next) { this .next = next; } public boolean doFilter(HttpServletRequest request); public void getNext() { return this .next; } .next; } }
定义具体处理程序:
现在,让我们定义链中的第一个过滤器类,它将阻止来自可疑IP地址的请求:
public class SuspiciousRequestFilter extends RequestFilter { public SuspiciousRequestFilter(RequestFilter next) { super (next); } public boolean doFilter(HttpServletRequest request) { if (hasMaliciousIntent(request.getRemoteAddr()) { //blocks the request return false ; } else if (next == null ) { //filter chain ended return false ; } return this .getNext().doFilter(request); } public boolean hasMaliciousIntent(String ipAddress) { ... } }
同样,让我们定义链中的第二个过滤器,它将阻止未授权的请求:
public class UnauthorizedRequestFilter extends RequestFilter { public UnauthorizedRequestFilter(RequestFilter next) { super (next); } public boolean doFilter(HttpServletRequest request) { if (isUserUnauthorized(request)) { //blocks the request return false ; } else if (next == null ) { //filter chain ended return false ; } return this .getNext().doFilter(request); } public boolean isUserUnauthorized(HttpServletRequest request) { ... } }
最后一个过滤器将识别和阻止尝试登录次数超出的用户:
public class ExceededLoginAttemptsRequestFilter extends RequestFilter { public ExceededLoginAttemptsRequestFilter(RequestFilter next) { super (next); } public boolean doFilter(HttpServletRequest request) { if (hasExceededLoginAttempts(request)) { //blocks the request return false ; } else if (next == null ) { //filter chain ended return false ; } return this .getNext().doFilter(request); } public boolean hasExceededLoginAttempts(HttpServletRequest request) { ... } }
调用链:
最后,是时候将它们编织成链了:
HttpServletRequest httpServletRequest = ... //the last filter in our chain RequestFilter exceededAttemptsFilter = new ExceededLoginAttemptsRequestFilter( null ); RequestFilter unauthorizedFilter = new UnauthorizedRequestFilter(exceededAttemptsFilter); RequestFilter suspiciousActivityFilter = new SuspiciousRequestFilter(unauthorizedFilter); suspiciousActivityFilter.doFilter(httpServletRequest);
在这里,每个用户请求将遵循以下过滤链:
这些过滤条件之一一旦被匹配,匹配的过滤器就会过滤掉该用户请求。 这也意味着剩余的链将被跳过。
结论:
在本教程中,我们学习了如何以及何时使用“责任链”设计模式。
翻译自: https://www.javacodegeeks.com/2019/09/chain-of-responsibility-design-pattern-in-java.html