【责任链】模式解决流程中多个接口的流程问题

业务需求

整体流程有5步骤,每个步骤调用一个接口,每个接口成功才能进行下一步。如a->b->c->d->e,
比如入学报到
a:报班,根据名字生成学号uid
b:根据学号分配班级获取班级编号cid
c:根据cid分配宿舍获取宿舍标号hid;
d:交学费
e:报道流程走完,结束,进入宿舍

使用模式:
责任链模式
模板方法模式
命令模式
设计模式不做介绍,具体可点击链接
【设计模式】常用的设计模式详解

代码

具体实现

1.定义上下文类

public class ProcessContext {
    private final String traceId;
    private Object resultA;
    private Object resultB;
    private Object resultC;
    private Object resultD;
    private Object resultE;

    public ProcessContext(String traceId) {
        this.traceId = traceId;
    }

    // Getters and Setters
    public String getTraceId() { return traceId; }
    public Object getResultA() { return resultA; }
    public void setResultA(Object resultA) { this.resultA = resultA; }
    // 其他结果的getter和setter类似
}

2.定义处理器接口

import java.util.concurrent.CompletableFuture;

public interface Processor {
    CompletableFuture<Void> process(ProcessContext context);
}

3.实现各个接口处理器

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

public class ProcessorA implements Processor {
    private final Executor executor;
    private final ServiceA serviceA;

    public ProcessorA(Executor executor, ServiceA serviceA) {
        this.executor = executor;
        this.serviceA = serviceA;
    }

    @Override
    public CompletableFuture<Void> process(ProcessContext context) {
        return CompletableFuture.runAsync(() -> {
            try {
                Object result = RetryUtil.executeWithRetry(() -> 
                    serviceA.callA(context.getTraceId()), 3);
                context.setResultA(result);
            } catch (Exception e) {
                throw new RuntimeException("ProcessorA failed after 3 retries", e);
            }
        }, executor);
    }
}

// 其他处理器类似(ProcessorB, ProcessorC等)

4.重试工具类

public class RetryUtil {
    public static <T> T executeWithRetry(Supplier<T> supplier, int maxRetries) {
        int retry = 0;
        while (retry < maxRetries) {
            try {
                return supplier.get();
            } catch (Exception e) {
                retry++;
                if (retry == maxRetries) {
                    throw new RuntimeException("Retry failed after " + maxRetries + " attempts", e);
                }
            }
        }
        throw new IllegalStateException("Should not reach here");
    }
}

5.服务示例

public class ServiceA {
    public Object callA(String traceId) {
        // 实际调用接口A的逻辑,使用traceId进行日志追踪
        return new Object(); // 模拟返回结果
    }
}

6.流程管理器

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

public class ProcessManager {
    private final ProcessorA processorA;
    private final ProcessorB processorB;
    private final ProcessorC processorC;
    private final ProcessorD processorD;
    private final ProcessorE processorE;

    public ProcessManager(Executor executor, ServiceA a, ServiceB b, ServiceC c, ServiceD d, ServiceE e) {
        this.processorA = new ProcessorA(executor, a);
        this.processorB = new ProcessorB(executor, b);
        this.processorC = new ProcessorC(executor, c);
        this.processorD = new ProcessorD(executor, d);
        this.processorE = new ProcessorE(executor, e);
    }

    public CompletableFuture<Void> startProcess(String traceId) {
        ProcessContext context = new ProcessContext(traceId);
        return processorA.process(context)
                .thenCompose(v -> processorB.process(context))
                .thenCompose(v -> processorC.process(context))
                .thenCompose(v -> processorD.process(context))
                .thenCompose(v -> processorE.process(context))
                .exceptionally(ex -> {
                    System.err.println("Process failed with traceId: " + traceId + ", error: " + ex.getMessage());
                    return null;
                });
    }
}

7.使用示例

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Main {
    public static void main(String[] args) {
        Executor executor = Executors.newFixedThreadPool(5);
        ServiceA a = new ServiceA();
        ServiceB b = new ServiceB();
        ServiceC c = new ServiceC();
        ServiceD d = new ServiceD();
        ServiceE e = new ServiceE();

        ProcessManager manager = new ProcessManager(executor, a, b, c, d, e);
        String traceId = "TRACE-" + System.currentTimeMillis();
        manager.startProcess(traceId).join();
    }
}

设计模式说明
责任链模式:每个处理器(ProcessorA~E)负责处理自己的任务,并将上下文传递给下一个处理器。

命令模式:每个处理器封装了具体的操作和重试逻辑。

异步处理:使用CompletableFuture和线程池实现异步调用链。

重试机制:通过RetryUtil统一处理重试逻辑,避免代码重复。

流程说明
生成唯一的traceId贯穿整个流程。

每个处理器通过上下文获取前一步的结果并调用接口。

任何一步重试三次失败后,整个流程终止。

使用异步线程池提高性能,避免阻塞主线程。

该实现满足异步调用、链式依赖、重试机制和唯一追踪标识的需求,结构清晰且易于扩展