职责链模式是一种行为设计模式,它允许将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求为止。每个处理者都可以选择将请求传递给下一个处理者或自行处理。
使用链表或数组来存储职责链节点,并在每个节点中定义一个方法来处理请求。每个节点都持有下一个节点的引用
- // 抽象处理者类
- abstract class Handler {
- protected Handler nextHandler;
-
- public void setNextHandler(Handler handler) {
- this.nextHandler = handler;
- }
-
- public abstract void handleRequest(Request request);
- }
-
- // 具体处理者类A
- class ConcreteHandlerA extends Handler {
- @Override
- public void handleRequest(Request request) {
- if (request.getType().equals("TypeA")) {
- // 处理请求
- System.out.println("ConcreteHandlerA处理了请求:" + request.getContent());
- } else {
- // 无法处理,传递给下一个处理者
- if (nextHandler != null) {
- nextHandler.handleRequest(request);
- } else {//已经遍历完了,表示没有节点能处理了
- System.out.println("无法处理该请求:" + request.getContent());
- }
- }
- }
- }
-
- // 具体处理者类B
- class ConcreteHandlerB extends Handler {
- @Override
- public void handleRequest(Request request) {
- if (request.getType().equals("TypeB")) {
- // 处理请求
- System.out.println("ConcreteHandlerB处理了请求:" + request.getContent());
- } else {
- // 无法处理,传递给下一个处理者
- if (nextHandler != null) {
- nextHandler.handleRequest(request);
- } else {//已经遍历完了,表示没有节点能处理了
- System.out.println("无法处理该请求:" + request.getContent());
- }
- }
- }
- }
-
- // 请求类
- class Request {
- private String type;
- private String content;
-
- public Request(String type, String content) {
- this.type = type;
- this.content = content;
- }
-
- public String getType() {
- return type;
- }
-
- public String getContent() {
- return content;
- }
- }
-
-
- public class Main {
-
- public static void main(String[] args) {
- Handler handlerA = new ConcreteHandlerA();
- Handler handlerB = new ConcreteHandlerB();
-
- handlerA.setNextHandler(handlerB);
-
- Request request1 = new Request("TypeA", "请求内容1");
- handlerA.handleRequest(request1); // 输出:ConcreteHandlerA处理了请求:请求内容1
-
- Request request2 = new Request("TypeB", "请求内容2");
- handlerA.handleRequest(request2); // 输出:ConcreteHandlerB处理了请求:请求内容2
-
- Request request3 = new Request("TypeC", "请求内容3");
- handlerA.handleRequest(request3); // 输出:无法处理该请求
-
- }
- }
在上述示例中,我们创建了两个具体的处理者类`ConcreteHandlerA`和`ConcreteHandlerB`,它们分别能够处理类型为"TypeA"和"TypeB"的请求。如果无法处理某个类型的请求,则将其传递给下一个处理者。
客户端代码中创建了职责链,并将具体的处理者按照顺序连接起来。然后通过调用第一个节点(即`handlerA`)的`handleRequest()`方法来触发整个职责链的执行。在实际应用中,可以根据实际需求进行扩展和修改,例如添加新的具体处理者类或修改判断条件等。
使用递归调用,在每个节点中判断是否需要继续传递请求给下一个节点
使用递归调用可以实现请求沿着职责链依次传递的功能。当一个处理者无法处理请求时,它会将请求传递给下一个处理者,并继续调用下一个处理者的处理方法,直到找到能够处理该请求的处理者为止。
- abstract class Handler {
- private Handler nextHandler;
-
- public void setNextHandler(Handler nextHandler) {
- this.nextHandler = nextHandler;
- }
-
- public void handleRequest(Request request) {
- if (canHandle(request)) {
- processRequest(request);
- } else if (nextHandler != null) {
- nextHandler.handleRequest(request);
- } else {
- System.out.println("无法处理该请求");
- }
- }
-
- protected abstract boolean canHandle(Request request);
-
- protected abstract void processRequest(Request request);
- }
-
- class ConcreteHandlerA extends Handler {
- @Override
- protected boolean canHandle(Request request) {
- return "TypeA".equals(request.getType());
- }
-
- @Override
- protected void processRequest(Request request) {
- System.out.println("ConcreteHandlerA处理了请求:" + request.getContent());
- // 具体处理逻辑...
- }
- }
-
- class ConcreteHandlerB extends Handler {
- @Override
- protected boolean canHandle(Request request) {
- return "TypeB".equals(request.getType());
- }
-
- @Override
- protected void processRequest(Request request) {
- System.out.println("ConcreteHandlerB处理了请求:" + request.getContent());
- // 具体处理逻辑...
- }
- }
-
- class Request {
- private String type;
- private String content;
-
- public Request(String type, String content) {
- this.type = type;
- this.content = content;
- }
-
- public String getType() {
- return type;
- }
-
- public String getContent() {
- return content;
- }
- }
-
-
- public class Main {
-
- public static void main(String[] args) {
- Handler handlerA = new ConcreteHandlerA();
- Handler handlerB = new ConcreteHandlerB();
-
- handlerA.setNextHandler(handlerB);
-
- Request request1 = new Request("TypeA", "请求内容1");
- handlerA.handleRequest(request1); // 输出:ConcreteHandlerA处理了请求:请求内容1
-
- Request request2 = new Request("TypeB", "请求内容2");
- handlerA.handleRequest(request2); // 输出:ConcreteHandlerB处理了请求:请求内容2
-
- Request request3 = new Request("TypeC", "请求内容3");
- handlerA.handleRequest(request3); // 输出:无法处理该请求
- }
- }
在上述示例中,我们创建了一个抽象处理者类Handler,实现了一个递归调用的处理方法,如果无法处理某个类型的请求,则将其递归传递给下一个处理者。然后创建了两个具体的处理者类ConcreteHandlerA
和ConcreteHandlerB
,它们分别能够处理类型为"TypeA"和"TypeB"的请求。
客户端代码中创建了职责链,并将具体的处理者按照顺序连接起来。然后通过调用第一个节点(即handlerA
)的handleRequest()
方法来触发整个职责链的执行。
在使用递归调用实现职责链模式时需要注意以下问题:
使用注解方式来动态生成职责链,提高灵活性和可配置性。
首先,我们需要定义一个抽象处理者类Handler
,它包含了设置下一个处理者的方法和处理请求的抽象方法。具体的处理者类将继承该抽象类并实现自己的业务逻辑。
创建Handle.java
- public abstract class Handler {
- private Handler nextHandler;
-
- public void setNextHandler(Handler nextHandler) {
- this.nextHandler = nextHandler;
- }
-
- public void handleRequest(Request request) {
- if (canHandle(request)) {
- process(request);
- } else if (nextHandler != null) {
- nextHandler.handleRequest(request);
- } else {
- System.out.println("无法护理该请求.");
- }
- }
-
- protected abstract boolean canHandle(Request request);
-
- protected abstract void process(Request request);
- }
接下来,我们创建两个具体的处理者类ConcreteHandlerA
和ConcreteHanderB
。这里假设它们分别能够处理类型为"TypeA"和"TypeB"的请求。
创建HandlerAnnotation.java
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface HandlerAnnotation {
- String type();
- }
创建ConcreteHanlderA.java
- @HandlerAnnotation(type = "TypeA")
- public class ConcreteHanlderA extends Handler {
-
- @Override
- protected boolean canHandle(Request request) {
- return "TypeA".equals(request.getType());
- }
-
- @Override
- protected void process(Request request) {
- // 处理 TypeA 类型请求的逻辑
- System.out.println("ConcreteHandlerA 处理了请求");
- }
- }
创建ConcreteHanlderB.java
- @HandlerAnnotation(type = "TypeB")
- public class ConcreteHandlerB extends Handler {
-
- @Override
- protected boolean canHandle(Request request) {
- return "TypeB".equals(request.getType());
- }
-
- @Override
- protected void process(Request request) {
- // 处理 TypeB 类型请求的逻辑
- System.out.println("ConcreteHandlerB处理了请求");
- }
- }
在上述代码中,我们使用了HandlerAnnotation
注解来标识具体处理者类能够处理的请求类型。
接下来,我们创建一个简单的请求类Request
,它包含一个类型属性和相应的getter方法。
创建Request.java
- public class Request {
- private String type;
-
- public Request(String type) {
- this.type = type;
- }
-
- public String getType() {
- return type;
- }
- }
最后,在客户端代码中扫描并构建职责链,并触发整个职责链的执行。
创建Main.java
- import java.lang.annotation.*;
- import java.util.ArrayList;
- import java.util.List;
- import java.io.File;
- import java.io.IOException;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.Enumeration;
- import java.util.List;
-
-
-
-
- public class Main {
-
- public static void main(String[] args) {
- List
handlers = new ArrayList<>(); -
- // 扫描具体处理者类上的注解信息,并创建处理者对象
- for (Class> clazz : getClasses()) {
- Annotation annotation = clazz.getAnnotation(HandlerAnnotation.class);
- if (annotation != null && Handler.class.isAssignableFrom(clazz)) {
- try {
- Handler handler = (Handler) clazz.getDeclaredConstructor().newInstance();
- handlers.add(handler);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- // 按照顺序连接处理者对象形成职责链
- int size = handlers.size();
- for (int i = 0; i < size - 1; i++) {
- handlers.get(i).setNextHandler(handlers.get(i + 1));
- }
-
- // 使用第一个节点(即handlers.get(0))来触发整个职责链的执行
- Request requestA = new Request("TypeA");
- handlers.get(0).handleRequest(requestA);
-
- Request requestB = new Request("TypeB");
- handlers.get(0).handleRequest(requestB);
-
- Request requestC = new Request("TypeC");
- handlers.get(0).handleRequest(requestC);
- }
-
- private static List
> getClasses() { - // 在这里返回具体处理者类所在的包路径下的所有类,或通过其他方式获取需要扫描的具体处理者类
- List
> classes = new ArrayList<>(); - String packageName = "com.example.posttest"; // 替换为具体处理者类所在的包路径
-
- try {
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- String path = packageName.replace('.', '/');
- Enumeration
resources = classLoader.getResources(path); -
- while (resources.hasMoreElements()) {
- URL resource = resources.nextElement();
- File file = new File(resource.getFile());
-
- if (file.isDirectory()) {
- for (File f : file.listFiles()) {
- if (f.isFile() && f.getName().endsWith(".class")) {
- String className = packageName + '.' + f.getName().substring(0, f.getName().length() - 6);
- Class> clazz = Class.forName(className);
- classes.add(clazz);
- }
- }
- }
- }
- } catch (IOException | ClassNotFoundException e) {
- e.printStackTrace();
- }
-
- return classes;
- }
- }
在上述示例中,我们为每个具体处理者类添加了HandlerAnnotation
注解,该注解标识了处理者所能处理的请求类型以及其在职责链中的位置。然后在客户端代码中扫描具体处理者类上的注解信息,并根据order值排序构建职责链。