You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中实现API链式调用的最优设计模式

针对你这种需要按顺序调用API、前一步响应作为后一步请求参数的场景,我推荐两种通用化的设计方案,既能避免重复的硬编码逻辑,又能满足你“初始阶段不了解请求上下文”的需求:

方案1:函数式接口 + 动态步骤链(最推荐)

这种方案利用Java 8+的函数式编程特性,让你可以动态组装API调用步骤——哪怕运行时才确定要执行哪些步骤,也能灵活添加。核心是用一个上下文类保存请求状态和累计输出,再把每个API调用封装成独立的步骤单元。

第一步:定义上下文类

用来统一管理请求对象、累计输出等状态:

public class ApiCallContext {
    private YourRequest req; // 替换成你的实际请求类
    private StringBuilder output = new StringBuilder();

    public ApiCallContext(YourRequest initialReq) {
        this.req = initialReq;
    }

    // 添加输出内容
    public void appendOutput(String content) {
        output.append(content);
    }

    // 获取最终拼接的输出
    public String getFinalOutput() {
        return output.toString();
    }

    // Getter和Setter,按需提供
    public YourRequest getReq() {
        return req;
    }

    public void setReq(YourRequest req) {
        this.req = req;
    }
}

第二步:定义步骤接口

用函数式接口简化步骤的定义:

@FunctionalInterface
public interface ApiStep {
    void execute(ApiCallContext context);
}

第三步:封装每个API调用为步骤

把你原来的每一段API调用逻辑,拆成独立的ApiStep实现:

// 第一个API调用步骤
public ApiStep firstApiCall() {
    return context -> {
        Response res = execute(context.getReq()); // 这里是你的execute方法
        context.appendOutput(res.getOut());
        context.getReq().setXYZ(res.getXYZ()); // 更新请求参数
    };
}

// 第二个API调用步骤
public ApiStep secondApiCall() {
    return context -> {
        Response res = execute(context.getReq());
        context.appendOutput(res.getOut());
        context.getReq().setABC(res.getABC());
    };
}

// 第三个API调用步骤
public ApiStep thirdApiCall() {
    return context -> {
        Response res = execute(context.getReq());
        context.appendOutput(res.getOut());
    };
}

第四步:构建执行器

用来按顺序执行所有步骤,支持动态添加:

public class ApiCallExecutor {
    private final List<ApiStep> steps = new ArrayList<>();

    // 链式调用添加步骤
    public ApiCallExecutor addStep(ApiStep step) {
        steps.add(step);
        return this;
    }

    // 执行所有步骤并返回最终结果
    public String execute(YourRequest initialReq) {
        ApiCallContext context = new ApiCallContext(initialReq);
        for (ApiStep step : steps) {
            step.execute(context);
        }
        return context.getFinalOutput();
    }
}

使用示例

你可以根据运行时的上下文动态添加步骤,比如根据初始请求的参数决定要不要跳过某个步骤:

public static void main(String[] args) {
    YourRequest initialReq = new YourRequest();
    // 初始化请求参数...

    ApiCallExecutor executor = new ApiCallExecutor()
            .addStep(firstApiCall())
            .addStep(secondApiCall());

    // 比如根据初始请求的某个条件,决定是否添加第三个步骤
    if (initialReq.needThirdCall()) {
        executor.addStep(thirdApiCall());
    }

    String finalOutput = executor.execute(initialReq);
    System.out.println("Final response::" + finalOutput);
}

这个方案的优势:

  • 每个API调用逻辑完全解耦,单独维护
  • 支持动态调整步骤(添加、移除、调整顺序),完美适配“初始不了解上下文”的场景
  • 代码简洁,利用函数式接口减少冗余

方案2:模板方法模式(适合固定流程场景)

如果你的API调用流程有固定的骨架(比如必须按A→B→C的顺序执行,只是每个步骤的细节可能变化),可以用模板方法模式封装固定流程,具体步骤由子类实现。

定义抽象模板类

封装固定的执行流程,把可变的步骤抽象成方法:

public abstract class AbstractApiFlow {
    protected YourRequest req;
    protected StringBuilder output = new StringBuilder();

    public AbstractApiFlow(YourRequest initialReq) {
        this.req = initialReq;
    }

    // 模板方法:固定执行流程
    public final String runFlow() {
        executeFirstApi();
        executeSecondApi();
        executeThirdApi();
        return output.toString();
    }

    // 抽象方法:每个步骤的具体实现由子类完成
    protected abstract void executeFirstApi();
    protected abstract void executeSecondApi();
    protected abstract void executeThirdApi();

    // 通用的API执行方法,抽出来复用
    protected Response callApi(YourRequest request) {
        return execute(request); // 你的execute方法
    }
}

实现具体流程类

public class DefaultApiFlow extends AbstractApiFlow {
    public DefaultApiFlow(YourRequest initialReq) {
        super(initialReq);
    }

    @Override
    protected void executeFirstApi() {
        Response res = callApi(req);
        output.append(res.getOut());
        req.setXYZ(res.getXYZ());
    }

    @Override
    protected void executeSecondApi() {
        Response res = callApi(req);
        output.append(res.getOut());
        req.setABC(res.getABC());
    }

    @Override
    protected void executeThirdApi() {
        Response res = callApi(req);
        output.append(res.getOut());
    }
}

使用示例

public static void main(String[] args) {
    YourRequest initialReq = new YourRequest();
    AbstractApiFlow flow = new DefaultApiFlow(initialReq);
    String finalOutput = flow.runFlow();
    System.out.println("Final response::" + finalOutput);
}

这个方案适合流程相对固定的场景,如果后续有不同的流程变体,可以创建不同的子类,但灵活性不如第一个方案。

为什么责任链模式不适用?

你说得对,责任链模式更适合“请求传递,每个处理器决定是否处理”的场景,比如请求过滤、日志处理等。它的核心是请求的分发或过滤,而不是你这种必须按顺序执行、每个步骤依赖前一步结果修改请求状态的流水线场景——而且责任链通常需要提前构建好链的结构,不太适配“初始不了解上下文”的动态需求。

内容的提问来源于stack exchange,提问作者goosebump

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:04:31