关于责任链模式的优雅实现
目录
什么是责任链模式
责任链模式(Chain of Responsibility Pattern)是一种常用的设计模式,它为请求创建了一个接收者对象的链。这种模式给予请求者一种将请求发送给一个对象并沿着这条链传递直到有一个对象处理它为止的方式。
责任链模式在开发中的应用
责任链模式在开发中有很多应用场景,例如日志记录、权限验证、过滤器等。它可以将复杂的业务逻辑拆分成多个独立的处理器,每个处理器负责处理特定类型的请求。
Java实现示例
下面是一个使用Java语言实现责任链模式的示例:
public interface Handler<T> {
boolean handle(T context);
default boolean isAsync() {
return false;
}
default boolean logTrace() {
return true;
}
}
@Slf4j
public class CommonPipeline<T> {
private List<Handler<T>> handlers = new LinkedList<>();
private ExecutorService executorService;
public CommonPipeline(int threadPoolSize) {
this.executorService = new ThreadPoolExecutor(threadPoolSize, threadPoolSize * 2, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
public void addHandler(Handler<T> handler) {
handlers.add(handler);
}
这段代码定义了一个通用的管道类。它包含了一个处理器列表和一个执行器服务。构造函数接受一个线程池大小作为参数,并创建了一个线程池执行器。
管道类还包含了一个addHandler方法,用于向处理器列表中添加处理器。
接下来,让我们看一下管道类的execute方法:
public void execute(T context) {
String pipelineId = UUID.randomUUID().toString();
long startTime = System.currentTimeMillis();
AtomicBoolean fastFail = new AtomicBoolean(false);
log.info("Starting pipeline execution. Pipeline ID: " + pipelineId);
for (Handler<T> handler : handlers) {
if (fastFail.get()) {
log.warn("Fast fail triggered. Stopping execution. Pipeline ID: " + pipelineId);
break;
}
if (handler.logTrace()) {
log.info("Executing handler: " + handler.getClass() + ". Pipeline ID: " + pipelineId);
}
try {
if (handler.isAsync()) {
executorService.submit(() -> {
if (!handler.handle(context)) {
fastFail.set(true);
}
});
} else {
if (!handler.handle(context)) {
log.warn("Handler " + handler.getClass().getSimpleName() + " failed. Stopping execution. Pipeline ID: " + pipelineId);
fastFail.set(true);
break;
}
}
} catch (Exception e) {
log.error("An error occurred while executing handler: " + handler.getClass() + ". Pipeline ID: " + pipelineId, e);
fastFail.set(true);
break;
}
}
这个方法接受一个上下文对象作为参数,并执行管道中的所有处理器。它首先生成了一个唯一的管道ID,并记录了开始时间。然后,它初始化了一个快速失败标志。
在循环中,该方法遍历所有处理器,并检查快速失败标志是否已经触发。如果触发,则停止执行并退出循环。
对于每个处理器,该方法会检查是否需要记录跟踪信息。如果是,则记录当前正在执行的处理器。
然后,该方法会尝试执行当前处理器。如果处理器是异步的,则使用执行器服务提交任务;否则直接调用handle方法。
如果handle方法返回false,则表示当前处理器执行失败。此时,该方法会根据快速失败标志进行相应操作:如果快速失败标志已经触发,则停止执行并退出循环;否则继续执行下一个处理器。
在这段代码中,我们可以看到异步和快速失败两个重要概念。
异步指的是某些操作可以在后台运行而不阻塞主线程。在这个例子中,如果某个处理器是异步的,则它会被提交到线程池中运行而不阻塞主线程。
快速失败指的是当某个操作失败时立即停止整个流程而不再继续尝试其他操作。在这个例子中,如果某个处理器返回false或抛出异常,则整个管道会立即停止运行而不再尝试其他处理器。
希望这篇博客能够帮助你更好地理解责任链模式。