职责链模式是一种行为设计模式,它允许将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求为止。每个处理者都可以选择将请求传递给下一个处理者或自行处理。
使用链表或数组来存储职责链节点,并在每个节点中定义一个方法来处理请求。每个节点都持有下一个节点的引用
// 抽象处理者类
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值排序构建职责链。