一、什么是职责链模式
职责链模式是一种行为设计模式,它允许你将请求沿着处理链进行传递,直到有一个对象处理它为止。
在职责链模式中,每个处理者都有自己的处理逻辑和下一个处理者的引,当一个请求到达时,它首先由第一个处理者尝试处理,如果处理者能够处理该请求,则处理结束;如果处理者无法处理该请求,则将请求传递给下一个处理者,依次类推,直到有一个处理者处理请求或者处理链结束。
职责链模式主要优点是解耦了发送者和接收者,使得请求的发送者不需要知道请求是如何被处理的,也不需要知道具体的处理者是谁。这样可以方便地添加、删除或者重新排序处理者,灵活地组织处理链。
在 Java 中,职链模式通常由一个抽象处理者和多个具体处理者组成。抽象处理者定义了处理请求的接口和一个指向下一个处理者的引用,具体处理者实现了处理请求的方法,并决定是否将请求传递给下一个处理者使用职责链模式可以很好地解决以下 2 22 个场景。
- 在一个系统中,多个对象可以处理同一个请求,但是具体由哪个对象来处理需要运行时刻动态确定。
- 系统需要动态地组织和管理一条处理链,而不需要手动编写大量的条件语句。
总之,职责链模式可以帮助降低系统的耦合度,提高代码的灵活性和可扩展性。
二、职责链模式实例
下面是一个使用Java实现职责链模式的例子,请同学们复制到本地执行。
首先,我们需要创建一个抽象的处理者类,定义处理请求的接口和一个指向下一个处理者的引用,代码如下。
public abstract class Handler { protected Handler nextHandler; public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; } public abstract void handleRequest(Request request); }
然后,我们创建具体的处理者(ConcreteHandler)类,实现处理请求的方法,并决定是否将请求传递给下一个处理者,代码如下。
public class ConcreteHandlerA extends Handler { @Override public void handleRequest(Request request) { if (request.getType().equals("TypeA")) { System.out.println("ConcreteHandlerA handles the request."); } else if (nextHandler != null) { nextHandler.handleRequest(request); } } } public class ConcreteHandlerB extends Handler { @Override public void handleRequest(Request request) { if (request.getType().equals("TypeB")) { System.out.println("ConcreteHandlerB handles the request."); } else if (nextHandler != null) { nextHandler.handleRequest(request); } } } public class ConcreteHandlerC extends Handler { @Override public void handleRequest(Request request) { if (request.getType().equals("TypeC")) { System.out.println("ConcreteHandlerC handles the request."); } else if (nextHandler != null) { nextHandler.handleRequest(request); } } }
最后,我们创建一个请求(Request)类,用于封装需要处理的请求,代码如下。
public class Request { private String type; public Request(String type) { this.type = type; } public String getType() { return type; } }
现在,我们可以创建一个处理链,并使用职责链模式处理请求,代码如下。
public class Main { public static void main(String[] args) { Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); Handler handlerC = new ConcreteHandlerC(); handlerA.setNextHandler(handlerB); handlerB.setNextHandler(handlerC); Request request1 = new Request("TypeA"); handlerA.handleRequest(request1); Request request2 = new Request("TypeB"); handlerA.handleRequest(request2); Request request3 = new Request("TypeC"); handlerA.handleRequest(request3); } }
输出结果为:
ConcreteHandlerA handles the request. ConcreteHandlerB handles the request. ConcreteHandlerC handles the request.
在这个例子中,我们创建了三个具体的处理者,分别是 ConcreteHandlerA
、ConcreteHandlerB
和 ConcreteHandlerC
。
每个处理者根据请求的类型来决定是否处理请求,如果不能处理,则将请求传递给下一个处理者。
最后,我们创建一个处理链,将处理者按顺序连接起来,并使用职责链模式处理请求。
三、职责链模式的应用场景
职责链模式适用于以下 4 44 个应用场景,请同学们认真学习。
- 请求发送者不关心请求的处理细节:职责链模式将发送者和接收者解耦,发送者不需要知道请求是如何被处理的,也不需要知道具体的处理者是谁。这样可以方便地添加、删除或者重新排序处理者,灵活地组织处理链。
- 处理请求的对象需要根据运行时刻动态确定:职责链模式允许将请求沿着处理链进行传递,直到有一个对象处理它为止。每个处理者都有自己的处理逻辑和下一个处理者的引用,可以根据具体情况动态地确定请求由哪个对象来处理。
- 需要动态地组织和管理一条处理链:职责链模式可以方便地添加、删除或者重新排序处理者,灵活地组织处理链。可以根据不同的需求,动态地调整处理链的结构。
- 多个对象可以处理同一个请求:职责链模式可以将请求沿着处理链进行传递,直到有一个对象处理它为止。每个处理者都有机会处理请求,可以根据具体情况来决定是否处理或者传递给下一个处理者。
职责链模式在实际开发中有很多应用场景,比如有以下 4 44 点。
- 日志处理:多个日志处理器可以组成一个处理链,每个处理器根据日志的级别来决定是否处理或者传递给下一个处理器。
- 异常处理:多个异常处理器可以组成一个处理链,每个处理器根据异常的类型来决定是否处理或者传递给下一个处理器。
- 权限校验:多个权限校验处理器可以组成一个处理链,每个处理器根据权限的级别来决定是否处理或者传递给下一个处理器。
- 请求过滤:多个请求过滤器可以组成一个处理链,每个过滤器根据请求的特征来决定是否处理或者传递给下一个过滤器。
总之,职责链模式可以帮助降低系统的耦合度,提高代码的灵活性和可扩展性,在处理需求复杂、处理逻辑多样的场景中具有很好的应用价值。
四、职责链模式面试题
- 什么是职责链模式?它的作用是什么?
- 职责链模式的角色有哪些?请简要描述每个角色的作用。
- 职责链模式和策略模式有何区别?
- 如何实现一个职责链模式?请简要描述该模式的实现步骤。
- 职责链模式的优缺点是什么?
- 职责链模式适用于哪些场景?请举例说明。
- 在职责链模式中,如何确定请求由哪个处理者来处理?
- 职责链模式和装饰器模式有何异同点?
- 职责链模式和观察者模式有何异同点?
- 在职责链模式中,如何防止请求形成无限循环?